CardView с другим радиусом угла

У меня есть следующий CardView, и я хочу установить разный радиус для каждого угла карты. Можно ли изменить их с помощью XML или программно? Заранее спасибо.

<android.support.v7.widget.CardView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginRight="16dp"
    android:layout_marginLeft="16dp"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="5dp"
    app:cardCornerRadius="0dp"
    app:cardElevation="0dp">
</android.support.v7.widget.CardView>

EDIT Как предлагает Авинаш, я ищу поведение этой библиотеки github.com/ Captain-miao/OptionRoundCardview, но с использованием элемента CardView по умолчанию. Если невозможно изменить его индивидуально, эта библиотека является хорошим подходом.


comment
В случае, если нам просто нужно сформировать изображение, используйте материал ShapeableImageView, который рисует растровое изображение с предоставленной фигурой.   -  person Anoop M Maddasseri    schedule 09.06.2021


Ответы (4)


Для этого требуется официальный MaterialCardView (расширяет androidx.cardview.widget.CardView) и не ниже версии 1.1.0 Библиотека компонентов материалов.

Добавьте в макет MaterialCardView:

    <com.google.android.material.card.MaterialCardView
        style="@style/CustomCardViewStyle"
        ...>
      
    </com.google.android.material.card.MaterialCardView>

Определите собственный стиль, наследующий стиль карточки материала (например, Widget.MaterialComponents.CardView), и используйте shapeAppearanceOverlay атрибут:

  <style name="CustomCardViewStyle" parent="@style/Widget.MaterialComponents.CardView">
     <item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay_card_custom_corners</item>
  </style>


  <style name="ShapeAppearanceOverlay_card_custom_corners" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">4dp</item>
    <item name="cornerSizeTopLeft">8dp</item>
    <item name="cornerSizeBottomRight">16dp</item>
    <item name="cornerSizeBottomLeft">0dp</item>
  </style>

введите здесь описание изображения

Вы также можете сделать это программно.
Просто примените пользовательскую ShapeAppearanceModel в углы карты.
Что-то вроде:

float radius = getResources().getDimension(R.dimen.my_corner_radius);
cardView.setShapeAppearanceModel(
  cardView.getShapeAppearanceModel()
      .toBuilder()
      .setTopLeftCorner(CornerFamily.ROUNDED,..)
      .setTopRightCorner(CornerFamily.ROUNDED,..)
      .setBottomRightCorner(CornerFamily.ROUNDED,radius)
      .setBottomLeftCornerSize(0)
      .build());

Примечание. для этого требуется библиотека версии 1.1.0.


С помощью Jetpack compose 1.0.0 (проверено с 1.0.0-rc02) вы можете использовать что-то вроде:

    Card(
        shape = RoundedCornerShape(
           4.dp,
           8.dp,
           16.dp,
           2.dp)
    ){
        Text("Content Card")
    }

введите здесь описание изображения

person Gabriele Mariotti    schedule 07.09.2019
comment
Привет Габриэль, спасибо за ваш ответ. Этот пример можно было бы сделать без Android x? - person Juanje; 09.09.2019
comment
@Juanje Нет, для новой библиотеки компонентов материалов требуется androidx - person Gabriele Mariotti; 09.09.2019
comment
Спасибо @Gabriele, тогда я попробую. - person Juanje; 09.09.2019
comment
Это не работает. shapeAppearanceOverlay красного цвета - person OhhhThatVarun; 12.09.2019
comment
@VarunRaj Требуется 1.1.0 (как описано в ответе). В настоящее время 1.1.0-альфа10 - person Gabriele Mariotti; 12.09.2019
comment
@GabrieleMariotti - если бы вы могли добавить правильный implementation ..... alpha...., это сэкономило бы таким людям, как я, пару минут :) - person Krzysztof Kubicki; 04.11.2019
comment
@GabrieleMariotti, знаете ли вы способ заставить ImageView внутри MaterialCardView учитывать новые закругленные углы и заполнять всю область? - person Krzysztof Kubicki; 04.11.2019
comment
@KrzysztofKubicki Есть несколько решений. Например, вы можете использовать ShapableImageView в библиотеке компонентов материалов. Проверьте этот ответ. - person Gabriele Mariotti; 30.12.2019

Вы можете создать собственный xml и назвать его rounded_corners.xml следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1dp"
    android:topLeftRadius="20dp"
    android:topRightRadius="30dp"
    android:bottomLeftRadius="40dp"
    android:bottomRightRadius="50dp"/>
<solid android:color="your_background_color" />
</shape>

А затем используйте это как фон для вашего CardView:

android:background="@drawable/rounded_corners"

EDIT: я только что заметил, что это может работать для всех других представлений, кроме CardView, поэтому обратитесь к этот вопрос, чтобы узнать, как найти обходной путь.

person Vucko    schedule 04.07.2018
comment
Вы правы, этот подход не работает для CardViews. Я уже проверил сообщение, которое вы предлагаете, но я думаю, что это грязное решение. Я искал что-то более чистое, например, изменение этих атрибутов из кода. Спасибо, в любом случае! - person Juanje; 04.07.2018
comment
Да, я заметил, что это обходной путь. Кажется, нет хорошего способа сделать это. - person Vucko; 07.07.2018
comment
это не работает для просмотра карт, поэтому этот ответ больше не подходит для этого вопроса. - person Amir Dora.; 26.10.2020

ПРИМЕЧАНИЕ. Это обходной путь, если вы хотите получить закругленные углы только внизу и обычные углы вверху. Это не сработает, если вы хотите иметь разные радиусы для всех четырех углов карты. Для этого вам придется использовать карточку материала или какую-то стороннюю библиотеку.

Вот что, похоже, сработало для меня:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#F9F9F9">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="@drawable/profile_bg"/>

    </androidx.cardview.widget.CardView>

    <androidx.cardview.widget.CardView
        android:id="@+id/cvProfileHeader"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardCornerRadius="32dp">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="280dp"
            android:orientation="vertical"
            android:background="@drawable/profile_bg"
            android:id="@+id/llProfileHeader"
            android:gravity="center_horizontal">

            <!--Enter your code here-->

        </LinearLayout>
    
    </androidx.cardview.widget.CardView>

</RelativeLayout>

Всего два кардвью. Второй вид карты будет иметь закругленные углы (как обычно со всех сторон) и будет содержать все остальные подвиды под ним. Первый вид карты над ним также находится на том же уровне (высоты) и имеет тот же фон, но составляет примерно половину высоты второго вида карты и не имеет закругленных углов (только обычные острые углы). Таким образом, я смог добиться частично закругленных углов снизу и нормальных углов сверху. Но для всех четырех сторон вам, возможно, придется использовать карточку материала.

person Max    schedule 15.10.2020

Привет, вы можете добавить его программно или с помощью xml со следующим кодом.

app:cardCornerRadius="0dp"// xml
cardView.setRadius(0);

это лишний кто ищет высоты

app:cardElevation="0.7dp"//xml
app:cardMaxElevation="1dp"//xml
cardView.setCardElevation(2.1f);//code
cardView.setMaxCardElevation(3f);//code

Полное Java-представление XML CardView.

CardView cardView = (CardView) findViewById(R.id.cardView);
cardView.setUseCompatPadding(true);
cardView.setContentPadding(30, 30, 30, 0);
cardView.setPreventCornerOverlap(true);
cardView.setCardBackgroundColor(Color.WHITE);
cardView.setCardElevation(2.1f);
cardView.setRadius(0);
cardView.setMaxCardElevation(3f);
person Avinash Ajay Pandey    schedule 04.07.2018
comment
Это решение устанавливает все углы CardView, я хочу установить только один, например, topLeft. - person Juanje; 04.07.2018
comment
ладно, понял вашу точку зрения непосредственно с картами, которых вы не можете легко достичь, поэтому я предлагаю вам использовать некоторые сторонние библиотеки. github.com/captain-miao/OptionRoundCardview проверьте это - person Avinash Ajay Pandey; 04.07.2018
comment
Да, вы правы, я уже проверил этот проект. Это мой следующий шаг, если я не получу никакого решения с CardView. Спасибо! Ценю твою помощь! - person Juanje; 04.07.2018