Como fazer uma vista com cantos arredondados?

92

Estou tentando fazer uma visualização no android com bordas arredondadas. A solução que encontrei até agora é definir uma forma com cantos arredondados e usá-la como plano de fundo dessa vista.

Aqui está o que eu fiz, defina um drawable conforme mostrado abaixo:

<padding
android:top="2dp"
android:bottom="2dp"/>
<corners android:bottomRightRadius="20dp"
android:bottomLeftRadius="20dp"
android:topLeftRadius="20dp"
android:topRightRadius="20dp"/>

Agora eu usei isso como plano de fundo para meu layout conforme abaixo:

<LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="10dp"
        android:clipChildren="true"
        android:background="@drawable/rounded_corner">

Isso funciona perfeitamente bem, posso ver que a visualização tem bordas arredondadas.

Mas meu layout tem muitas outras visualizações filho, digamos um ImageView ou a MapView. Quando coloco um ImageViewdentro do layout acima, os cantos da imagem não são cortados / cortados, em vez disso, ela parece cheia.

Eu vi outras soluções alternativas para fazê-lo funcionar como o explicado aqui .

Mas existe um método para definir cantos arredondados para uma visualização e todas as visualizações filhas estão contidas na visualização principal que possui cantos arredondados?

Zach
fonte
E se você usar um layout personalizado estendendo-se para LinearLayout e, enquanto seu objeto é criado, iterar todos os filhos desse layout e aplicar fundo de borda arredondada a eles?
MysticMagicϡ
3
android.support.v7.widget.CardView parece ser a solução para isso
rocketspacer
Esta solução resolveu para mim, mas requer subclasses: /programming/5574212/android-view-clipping
Aaron
Isso responde sua pergunta? Adicionando bordas para imagem arredondada imagem android
user4157124

Respostas:

127

Outra abordagem é fazer uma classe de layout personalizada como a abaixo. Esse layout primeiro desenha seu conteúdo em um bitmap fora da tela, mascara o bitmap fora da tela com um retângulo arredondado e, em seguida, desenha o bitmap fora da tela na tela real.

Eu tentei e parece funcionar (pelo menos para o meu caso de teste simples). É claro que afetará o desempenho em comparação com um layout regular.

package com.example;

import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.widget.FrameLayout;

public class RoundedCornerLayout extends FrameLayout {
    private final static float CORNER_RADIUS = 40.0f;

    private Bitmap maskBitmap;
    private Paint paint, maskPaint;
    private float cornerRadius;

    public RoundedCornerLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
        maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

        setWillNotDraw(false);
    }

    @Override
    public void draw(Canvas canvas) {
        Bitmap offscreenBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas offscreenCanvas = new Canvas(offscreenBitmap);

        super.draw(offscreenCanvas);

        if (maskBitmap == null) {
            maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());
        }

        offscreenCanvas.drawBitmap(maskBitmap, 0f, 0f, maskPaint);
        canvas.drawBitmap(offscreenBitmap, 0f, 0f, paint);
    }

    private Bitmap createMask(int width, int height) {
        Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
        Canvas canvas = new Canvas(mask);

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);

        canvas.drawRect(0, 0, width, height, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);

        return mask;
    }
}

Use como um layout normal:

<com.example.RoundedCornerLayout
    android:layout_width="200dp"
    android:layout_height="200dp">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/test"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="#ff0000"
        />

</com.example.RoundedCornerLayout>
Jaap van Hengstum
fonte
1
Estou usando este layout para visualização de imagens com função de zoom dentro, mas esse layout não consegue detectar o ouvinte de toque quando tento fazer zoom. Como adicionar a função de ouvinte de toque neste layout?
Muhammad Nafian Wildana
2
Usei esse método e funciona bem. Mas quando coloco um EditText dentro do layout, a tela não é atualizada quando eu digito. Quando fecho a janela, o texto é exibido. A tela está sendo atualizada assim que fecho o teclado. Alguma correção para isso?
Sajib Acharya de
1
O único problema com isso quando você o usa com o modo de exibição Recycler é que ele não está esperando que um conjunto completo de itens seja carregado. E ronda apenas alguns itens. Existe uma razão para isso acontecer?
Ahmed
2
Isso não funciona com imagens carregadas da biblioteca glide que usam transições de espaço reservado (ou quaisquer outros filhos animados, na verdade). Eu tenho uma solução alternativa, mas requer que sua cor de fundo seja uma cor sólida. Consulte gist.github.com/grennis/da9f86870c45f3b8ae00912edb72e868
Greg Ennis
2
Solução fina e útil, mas muito cara. O RecyclerView com apenas seis elementos que contém uma imagem não pode rolar suavemente. E não depende da potência do dispositivo (Samsung S9 ou Wileyfox Swift 2). stackoverflow.com/a/41098690/4399323 é a melhor resposta!
Valentin Yuryev
71

Ou você pode usar um android.support.v7.widget.CardViewassim:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    card_view:cardBackgroundColor="@color/white"
    card_view:cardCornerRadius="4dp">

    <!--YOUR CONTENT-->
</android.support.v7.widget.CardView>
rocketspacer
fonte
Já tentei de tantas maneiras, a sua é a melhor solução para o meu problema. OBRIGADO!
wizChen de
Não é possível remover a elevação. Funciona bem se o projeto requer elevação.
Abdalrahman Shatou
1
@AbdalrahmanShatou developer.android.com/reference/android/support/v7/widget/… existem propriedades para isso. Você tentou defini-los como "0"?
rocketspacer de
5
Uma desvantagem é que ele não oferece suporte a <21 APIs do Android
Itai Spector
50

shape.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="#f6eef1" />

    <stroke
        android:width="2dp"
        android:color="#000000" />

    <padding
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />

    <corners android:radius="5dp" />

</shape>

e dentro do seu layout

<LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="10dp"
        android:clipChildren="true"
        android:background="@drawable/shape">

        <ImageView
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:src="@drawable/your image"
             android:background="@drawable/shape">

</LinearLayout>
Vaishali Sutariya
fonte
3
@Zach: De que forma não funcionou? O mesmo que seu aplicativo estava funcionando quando você fez a pergunta original?
LarsH
2
clipChildren é inútil e a visualização da imagem ainda se estende para fora da visualização.
Abdalrahman Shatou
1
Eu gostaria de poder te dar uma recompensa por isso. Obrigado
Odys
3
Não acho que essa abordagem funcione se a imagem for retangular, já que o plano de fundo será desenhado atrás do conteúdo da imagem. Isso pode funcionar apenas com imagens que tenham transparência e elas mesmas tenham cantos arredondados.
Harsha Vardhan
21

A resposta de Jaap van Hengstum funciona muito bem, entretanto eu acho que é caro e se aplicarmos esse método em um botão, por exemplo, o efeito de toque é perdido, pois a visualização é renderizada como um bitmap.

Para mim o melhor método e o mais simples consiste em aplicar uma máscara na vista, assim:

@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
    super.onSizeChanged(width, height, oldWidth, oldHeight);

    float cornerRadius = <whatever_you_want>;
    this.path = new Path();
    this.path.addRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, Path.Direction.CW);
}

@Override
protected void dispatchDraw(Canvas canvas) {
    if (this.path != null) {
        canvas.clipPath(this.path);
    }
    super.dispatchDraw(canvas);
}
Asno
fonte
Como usar isso?
Maksim Kniazev
@MaksimKniazev Faça uma subclasse do layout que você deseja (por exemplo: FrameLayout), em seguida, cole esses dois métodos nesta subclasse e substitua '<qualquer_you_want>' pelo valor do raio do canto desejado (de recursos, por exemplo). É isso aí. É bastante claro para você ou você precisa de um exemplo?
Donkey de
Muito obrigado, realmente funciona melhor para o RecyclerView!
Valentin Yuryev
18

Se você estiver tendo problemas ao adicionar ouvintes de toque ao layout. Use este layout como layout pai.

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.widget.FrameLayout;

public class RoundedCornerLayout extends FrameLayout {
    private final static float CORNER_RADIUS = 6.0f;
    private float cornerRadius;

    public RoundedCornerLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }


    @Override
    protected void dispatchDraw(Canvas canvas) {
        int count = canvas.save();

        final Path path = new Path();
        path.addRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), cornerRadius, cornerRadius, Path.Direction.CW);
        canvas.clipPath(path, Region.Op.REPLACE);

        canvas.clipPath(path);
        super.dispatchDraw(canvas);
        canvas.restoreToCount(count);
    }


}

Como

<?xml version="1.0" encoding="utf-8"?>
<com.example.view.RoundedCornerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/patentItem"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingRight="20dp">
        ... your child goes here
    </RelativeLayout>
</com.example.view.RoundedCornerLayout>
Sushant
fonte
2
Funciona bem se não houver muitas animações na tela, o que faz com que a tela se desenhe várias vezes; desde então, ele diminuirá o desempenho criticamente. Deve tentar o Cardview, que tem um método de canto arredondado eficiente (não use clipping path ou canvas.drawRoundRect - ruim na API 17 abaixo, mas use porterFilterDuffColor)
Nguyen Tan Dat
15

Crie um arquivo xml chamado round.xmlna drawablepasta e cole este conteúdo:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
  <solid android:color="#FFFFFF" />
  <stroke android:width=".05dp" android:color="#d2d2d2" />
  <corners android:topLeftRadius="5dp" android:topRightRadius="5dp" android:bottomRightRadius="5dp" android:bottomLeftRadius="5dp"/>
</shape>

em seguida, use round.xmlcomo backgroundpara qualquer item. Em seguida, você terá cantos arredondados.

Ajay Venugopal
fonte
9

No Android L, você poderá usar apenas View.setClipToOutline para obter esse efeito. Nas versões anteriores, não havia como apenas cortar o conteúdo de um ViewGroup aleatório em uma determinada forma.

Você terá que pensar em algo que lhe daria um efeito semelhante:

  • Se você só precisa de cantos arredondados no ImageView, pode usar um sombreador para 'pintar' a imagem sobre a forma que está usando como plano de fundo. Dê uma olhada nesta biblioteca para obter um exemplo.

  • Se você realmente precisa que todos os filhos sejam cortados, talvez possa outra visão sobre o seu layout? Um com um fundo da cor que você está usando e um 'buraco' redondo no meio? Na verdade, você poderia criar um ViewGroup personalizado que desenhasse essa forma sobre todos os filhos, substituindo o método onDraw.

Ivagarz
fonte
3

siga este tutorial e toda a discussão abaixo dele - http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/

de acordo com este post escrito por Guy Romain, um dos desenvolvedores líderes de todo o kit de ferramentas de IU do Android, é possível fazer um contêiner (e todas as suas visualizações filhas) com cantos arredondados, mas ele explicou que é muito caro (devido ao desempenho de problemas de renderização).

Eu recomendo que você vá de acordo com o post dele, e se você quiser cantos arredondados, implemente os cantos arredondados de ImageViewacordo com este post. em seguida, você pode colocá-lo dentro de um recipiente com qualquer plano de fundo e obterá o efeito que deseja.

foi o que eu também fiz eventualmente.

Tal Kanel
fonte
3

Você pode usar um androidx.cardview.widget.CardViewassim:

<androidx.cardview.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"       
        app:cardCornerRadius="@dimen/dimen_4"
        app:cardElevation="@dimen/dimen_4"
        app:contentPadding="@dimen/dimen_10">

       ...

</androidx.cardview.widget.CardView>

OU

shape.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="#f6eef1" />

    <stroke
        android:width="2dp"
        android:color="#000000" />

    <padding
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />

    <corners android:radius="5dp" />

</shape>

e dentro do seu layout

<LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/shape">

        ...

</LinearLayout>
Rahul
fonte
3

Crie um arquivo xml em sua pasta drawable com o código a seguir. (O nome do arquivo que criei é rounded_corner.xml)

rounded_corner.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">

        <!-- view background color -->
        <solid
            android:color="#a9c5ac" >
        </solid>

        <!-- view border color and width -->
        <stroke
            android:width="3dp"
            android:color="#1c1b20" >
        </stroke>

        <!-- If you want to add some padding -->
        <padding
            android:left="4dp"
            android:top="4dp"
            android:right="4dp"
            android:bottom="4dp"    >
        </padding>

        <!-- Here is the corner radius -->
        <corners
            android:radius="10dp"   >
        </corners>
    </shape>

E mantenha isso drawablecomo backgroundpara a vista para a qual você deseja manter a borda do canto arredondado. Vamos mantê-lo por umLinearLayout

    <LinearLayout android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/rounded_corner"
            android:layout_centerInParent="true">

            <TextView android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Hi, This layout has rounded corner borders ..."
                android:gravity="center"
                android:padding="5dp"/>

    </LinearLayout>
Rajneesh Shukla
fonte
3

O CardViewtrabalhou para mim em API 27 em Android Estúdio 3.0.1. O colorPrimaryfoi referenciado no res/values/colors.xmlarquivo e é apenas um exemplo. Para o layout_width, 0dpele se estenderá até a largura do pai. Você terá que configurar as restrições e largura / altura de acordo com suas necessidades.

<android.support.v7.widget.CardView
    android:id="@+id/cardView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:cardCornerRadius="4dp"
    app:cardBackgroundColor="@color/colorPrimary">

    <!-- put your content here -->

</android.support.v7.widget.CardView>
Lloyd Rochester
fonte
2

Diferença da resposta de Jaap van Hengstum:

  1. Use BitmapShader em vez de bitmap de máscara.
  2. Crie bitmap apenas uma vez.
public class RoundedFrameLayout extends FrameLayout {
    private Bitmap mOffscreenBitmap;
    private Canvas mOffscreenCanvas;
    private BitmapShader mBitmapShader;
    private Paint mPaint;
    private RectF mRectF;

    public RoundedFrameLayout(Context context) {
        super(context);
        init();
    }

    public RoundedFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RoundedFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setWillNotDraw(false);
    }

    @Override
    public void draw(Canvas canvas) {
        if (mOffscreenBitmap == null) {
            mOffscreenBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
            mOffscreenCanvas = new Canvas(mOffscreenBitmap);
            mBitmapShader = new BitmapShader(mOffscreenBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setShader(mBitmapShader);
            mRectF = new RectF(0f, 0f, canvas.getWidth(), canvas.getHeight());
        }
        super.draw(mOffscreenCanvas);

        canvas.drawRoundRect(mRectF, 8, 8, mPaint);
    }
}
Peter Zhao
fonte
2
public class RoundedCornerLayout extends FrameLayout {
    private double mCornerRadius;

    public RoundedCornerLayout(Context context) {
        this(context, null, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    public double getCornerRadius() {
        return mCornerRadius;
    }

    public void setCornerRadius(double cornerRadius) {
        mCornerRadius = cornerRadius;
    }

    @Override
    public void draw(Canvas canvas) {
        int count = canvas.save();

        final Path path = new Path();
        path.addRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), (float) mCornerRadius, (float) mCornerRadius, Path.Direction.CW);
        canvas.clipPath(path, Region.Op.REPLACE);

        canvas.clipPath(path);
        super.draw(canvas);
        canvas.restoreToCount(count);
    }
}
Mahmoud
fonte
2

Com a Biblioteca de Componentes de Materiais, a melhor maneira de fazer um Viewcom cantos arredondados é usar oMaterialShapeDrawable .

Crie um ShapeAppearanceModel com cantos arredondados personalizados:

ShapeAppearanceModel shapeAppearanceModelLL1 = new ShapeAppearanceModel()
        .toBuilder()
        .setAllCorners(CornerFamily.ROUNDED,radius16)
        .build();

Crie um MaterialShapeDrawable:

MaterialShapeDrawable shapeDrawableLL1 = new MaterialShapeDrawable(shapeAppearanceModeLL1);

Se você quiser aplicar também um elevationOverlay para o tema escuro, use isto:

MaterialShapeDrawable shapeDrawableLL1 = MaterialShapeDrawable.createWithElevationOverlay(this, 4.0f);
shapeDrawableLL1.setShapeAppearanceModel(shapeAppearanceModelLL1);

Opcional: aplique ao shapeDrawable uma cor de fundo e um traço

shapeDrawableLL1.setFillColor(
       ContextCompat.getColorStateList(this,R.color...));
 shapeDrawableLL1.setStrokeWidth(2.0f);
 shapeDrawableLL1.setStrokeColor(
       ContextCompat.getColorStateList(this,R.color...));

Por fim, aplique o shapeDrawable como plano de fundo em sua LinearLayout(ou em outra visualização):

LinearLayout linearLayout1= findViewById(R.id.ll_1);
ViewCompat.setBackground(linearLayout1,shapeDrawableLL1);

insira a descrição da imagem aqui

Gabriele Mariotti
fonte
1

O link do tutorial que você forneceu parece sugerir que você precisa definir as propriedades layout_width e layout_height dos seus elementos filhos para match_parent.

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
danielcooperxyz
fonte
0

experimente esta propriedade com seu layout linear. Isso ajudará nas
ferramentas: context = ". youractivity"


fonte
0
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {

        Bitmap roundedBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(roundedBitmap);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return roundedBitmap;
    }
Biswajit Karmakar
fonte
0

Para criar uma imagem de canto arredondado usando com.google.android.material: material: 1.2.0-beta01

 float radius = context.getResources().getDimension(R.dimen.border_radius_hug);
    shapeAppearanceModel = new ShapeAppearanceModel()
            .toBuilder()
            .setAllCorners(CornerFamily.ROUNDED,radius)
            .build();

imageView.setShapeAppearanceModel(shapeAppearanceModel)

ou se quiser usá-lo em um arquivo xml:

  <com.google.android.material.imageview.ShapeableImageView
            android:id="@+id/thumb"
            android:layout_width="80dp"
            android:layout_height="60dp"
            app:shapeAppearanceOverlay="@style/circleImageView"
            />

em style.xml adicione isto:

<style name="circleImageView" parent="">
      <item name="cornerFamily">rounded</item>
      <item name="cornerSize">10%</item>
</style>
Erfan Eghterafi
fonte
-1

Use forma em xml com retângulo. Defina a propriedade de raio inferior ou superior como desejado. Em seguida, aplique esse xml como plano de fundo para sua visualização .... ou ... use gradientes para fazer isso a partir do código.

Pratik Deogade
fonte
Já fiz isso, mas quer saber se existe um método melhor?
Zach
O solicitante já mencionou tentar essa abordagem em sua pergunta.
Michael Krause,