Есть ли способ изменить радиус определенного угла Material Design CardView?

Я использую материальный дизайн в своем приложении для Android и обычно для изменения радиуса угла карты я использую app:cardCornerRadius, но это изменит все четыре угла карты. Я хочу изменить любой конкретный угол карты. Я не хочу использовать drawable только для изменения угла. Есть ли способ через xml или программно.

 <com.google.android.material.card.MaterialCardView
        style="@style/Widget.MaterialComponents.CardView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/colorWhite"
        app:cardCornerRadius="16dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp" android:layout_marginEnd="16dp">
    <androidx.constraintlayout.widget.ConstraintLayout
            android:visibility="visible"
            android:layout_width="match_parent"
            android:layout_height="match_parent">



Ответы (3)


У меня есть решение, но для него требуется v21 Lollipop и выше. Вы можете сделать это программно следующим образом:

В вашем классе активности есть public static int radius = 20;, а в вашем Oncreate();

CardView card = findViewById(R.id.my_card);


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   makeCustomOutline(card);
}

затем определите функцию следующим образом:

 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void makeCustomOutline(CardView card){

    card.setOutlineProvider(new ViewOutlineProvider() {
        @Override
        public void getOutline(View view, Outline outline) {

            outline.setRoundRect(0, 0, view.getWidth(),
                    (view.getHeight() + radius), (float)radius );
        }
    });
    card.setClipToOutline(true);

}

с помощью метода setRoundRect() вы можете контролировать, какой угол карты получает радиус, а какой нет. Приведенный выше код сделает закругленными только верхние углы, нижние углы не будут закруглены.

Использованная литература:

Этот ответ был адаптирован из эта статья

документы в методе setRoundRect()

документы по ViewOutlineProvider

person Edgar    schedule 02.06.2019
comment
контур.setRoundRect(0, 0-радиус, view.getWidth(), (view.getHeight()), (плавающий) радиус); для закругленных углов нижний_левый и нижний_правый. - person Dharmesh G; 04.06.2020

С версией 1.1.0 компонента материала вы можете настройте форму вашего компонента с помощью атрибута shapeAppearanceOverlay.
Вы можете использовать его в представлении или в стиле.

<com.google.android.material.card.MaterialCardView
      .....
      app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialCardView.Cut">

а затем определите свою любимую форму:

  <style name="ShapeAppearanceOverlay.MaterialCardView.Cut" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">0dp</item>
    <item name="cornerSizeTopLeft">16dp</item>
    <item name="cornerSizeBottomRight">16dp</item>
    <item name="cornerSizeBottomLeft">16dp</item>
  </style>

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

С помощью кода вы можете применить пользовательскую ShapeAppearanceModel к угол карты, используя что-то вроде:

float radius = getResources().getDimension(R.dimen.my_corner_radius);
cardView.setShapeAppearanceModel(
  cardView.getShapeAppearanceModel()
      .toBuilder()
      .setAllCorners(CornerFamily.ROUNDED,radius)
      .setTopRightCornerSize(0)
      .build());
person Gabriele Mariotti    schedule 23.08.2019
comment
Отличный ответ! Я попробовал это программно, и он отлично работал, пока я не поместил imageView внутри MaterialCardView. В этом случае углы перекрываются изображением, поэтому кажется, что у карты нет углового радиуса... Мне нужен способ программно изменить угловой радиус без этой проблемы, есть идеи? - person Tiago Nunes; 18.03.2021
comment
@TiagoNunes пытается использовать ShapeableImageView - person Gabriele Mariotti; 18.03.2021
comment
К сожалению, это не сработает в моем случае использования, так как у меня есть горизонтальный просмотр изображений... - person Tiago Nunes; 18.03.2021

Я не совсем уверен, что карточка Material Design имеет эту функциональность или нет. Но я не думаю, что карточка по умолчанию имеет такую ​​​​функциональность, поэтому от имени этого карточного материала вы можете использовать

Эта библиотека (нажмите здесь).

Это просто мое мнение, может быть, для этого есть другое хорошее решение.

person Manthan Patel    schedule 01.06.2019
comment
Спасибо за помощь .... но я думаю, что если нет выбора, то лучше использовать drawable вместо библиотеки ... так что, может быть, я наконец предпочитаю рисовать. - person Amit Sen; 01.06.2019
comment
Да, вам решать, что вы хотите использовать. Я просто предлагаю это. - person Manthan Patel; 01.06.2019
comment
@ManthanPatel MaterialCardView обладает такой функциональностью. Нет необходимости в сторонних библиотеках - person Gabriele Mariotti; 07.09.2019
comment
@GabrieleMarriotti Да, ты прав. На этот ответ я ответил до того, как пришла материальная составляющая. - person Manthan Patel; 08.09.2019