¿Cómo hacer una vista con esquinas redondeadas?

94

Estoy tratando de hacer una vista en Android con bordes redondeados. La solución que encontré hasta ahora es definir una forma con esquinas redondeadas y usarla como fondo de esa vista.

Esto es lo que hice, definir un dibujable como se indica a continuación:

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

Ahora usé esto como fondo para mi diseño de la siguiente manera:

<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">

Esto funciona perfectamente bien, puedo ver que la vista tiene bordes redondeados.

Pero mi diseño tiene muchas otras vistas secundarias, por ejemplo, ImageView o MapView. Cuando coloco un ImageViewdiseño dentro del diseño anterior, las esquinas de la imagen no se recortan / recortan, sino que aparecen llenas.

He visto otras soluciones para que funcione como se explica aquí .

Pero, ¿existe un método para establecer esquinas redondeadas para una vista y todas sus vistas secundarias están contenidas dentro de esa vista principal que tiene esquinas redondeadas?

Zach
fuente
¿Qué sucede si usa un diseño personalizado que se extiende a LinearLayout y, mientras se crea su objeto, itera todos los elementos secundarios de ese diseño y les aplica un fondo de borde redondeado?
MysticMagicϡ
3
android.support.v7.widget.CardView parece ser la solución para esto
rocketspacer
Esta solución me lo resolvió, pero requiere subclases: /programming/5574212/android-view-clipping
Aaron
¿Responde esto a tu pregunta? Agregar bordes para imagen imagen redondeada android
user4157124
Google tiene un nuevo marco, las nuevas tecnologías son mejores [Jetpack Compose] [1] [1]: stackoverflow.com/questions/6054562/…
Ucdemir

Respuestas:

128

Otro enfoque es crear una clase de diseño personalizada como la que se muestra a continuación. Este diseño primero dibuja su contenido en un mapa de bits fuera de la pantalla, enmascara el mapa de bits fuera de la pantalla con un rectángulo redondeado y luego dibuja el mapa de bits fuera de la pantalla en el lienzo real.

Lo probé y parece funcionar (al menos para mi caso de prueba simple). Por supuesto, afectará el rendimiento en comparación con un diseño normal.

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 esto como un diseño 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
fuente
1
Estoy usando este diseño para la vista de imágenes con función de zoom en el interior, pero este diseño no puede detectar el oyente táctil cuando intento hacer zoom, ¿cómo agregar la función de oyente táctil en este diseño?
Muhammad Nafian Wildana
2
Usé este método y funciona bien. Pero cuando pongo un EditText dentro del diseño, la pantalla no se actualiza cuando escribo. Cuando cierro la ventana, el texto aparece en pantalla. La pantalla se actualiza una vez que cierro el teclado. ¿Alguna solución a esto?
Sajib Acharya
1
El único problema con esto cuando lo usa con la vista Recycler es que no está esperando a que se cargue el conjunto completo de elementos. Y redondea solo algunos elementos. ¿Hay alguna razón para que esto suceda?
Ahmed
2
Esto no funciona con imágenes cargadas desde la biblioteca de deslizamiento que usan transiciones de marcador de posición (o cualquier otro niño animado en realidad). Tengo una solución alternativa, pero requiere que el color de fondo sea un color sólido. Ver gist.github.com/grennis/da9f86870c45f3b8ae00912edb72e868
Greg Ennis
2
Solución fina y útil, pero demasiado cara. RecyclerView con solo seis elementos que contienen una imagen no puede desplazarse sin problemas. Y no depende de la potencia del dispositivo (Samsung S9 o Wileyfox Swift 2). stackoverflow.com/a/41098690/4399323 es la mejor respuesta.
Valentin Yuryev
73

O puedes usar un me android.support.v7.widget.CardViewgusta:

<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>
cohete espaciador
fuente
Lo he intentado de muchas formas, la tuya es la mejor solución a mi problema. ¡GRACIAS!
wizChen
No se puede quitar la elevación. Funciona bien si el diseño requiere elevación.
Abdalrahman Shatou
1
@AbdalrahmanShatou developer.android.com/reference/android/support/v7/widget/… hay propiedades para eso. ¿Ha intentado establecerlos en "0"?
rocketspacer
5
Un inconveniente es que no es compatible con las API de Android <21
Itai Spector
52

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>

y dentro de tu diseño

<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
fuente
3
@Zach: ¿De qué manera no funcionó? ¿Igual que funcionaba tu aplicación cuando hiciste la pregunta original?
LarsH
2
clipChildren es inútil y la vista de la imagen aún se extiende fuera de la vista.
Abdalrahman Shatou
1
Ojalá pudiera darte una recompensa por eso. Gracias
Odys
3
No creo que este enfoque funcione si la imagen es rectangular, ya que el fondo se dibujará detrás del contenido de la imagen. Es posible que esto solo funcione con imágenes que tengan transparencia y que tengan esquinas redondeadas.
Harsha Vardhan
23

La respuesta de Jaap van Hengstum funciona muy bien, sin embargo, creo que es costosa y si aplicamos este método en un botón, por ejemplo, el efecto táctil se pierde ya que la vista se representa como un mapa de bits.

Para mí el mejor método y el más sencillo consiste en aplicar una máscara en la vista, así:

@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);
}
Burro
fuente
¿Como usar esto?
Maksim Kniazev
@MaksimKniazev Cree una subclase del diseño que desee (por ejemplo: FrameLayout), luego pegue estos dos métodos en esta subclase y reemplace '<whatever_you_want>' con su valor de radio de esquina deseado (de los recursos, por ejemplo). Eso es. ¿Está lo suficientemente claro para usted o necesita un ejemplo?
Burro
¡Muchas gracias, realmente funciona mejor para RecyclerView!
Valentin Yuryev
18

Si tiene problemas al agregar oyentes táctiles al diseño. Utilice este diseño como diseño principal.

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
fuente
2
Funciona bien si no hay muchas animaciones en la pantalla, lo que hace que la pantalla se dibuje una y otra vez muchas veces; ya que, ralentizará el rendimiento de forma crítica. Debería probar cardview, que tiene un método de esquina redondeada eficiente (no use la ruta de recorte o canvas.drawRoundRect - mal en API 17 por debajo, pero use porterFilterDuffColor)
Nguyen Tan Dat
18

Cree un archivo xml llamado round.xmlen la drawablecarpeta y pegue este contenido:

<?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>

luego use el round.xmlcomo backgroundpara cualquier artículo. Entonces te dará esquinas redondeadas.

Ajay Venugopal
fuente
9

En Android L, podrá usar View.setClipToOutline para obtener ese efecto. En versiones anteriores, no hay forma de recortar el contenido de un ViewGroup aleatorio en una forma determinada.

Tendrás que pensar en algo que te dé un efecto similar:

  • Si solo necesita esquinas redondeadas en ImageView, puede usar un sombreador para 'pintar' la imagen sobre la forma que está usando como fondo. Eche un vistazo a esta biblioteca para ver un ejemplo.

  • Si realmente necesita que se recorten todos los niños, ¿quizás pueda otra vista sobre su diseño? ¿Uno con un fondo de cualquier color que estés usando y un 'agujero' redondo en el medio? De hecho, podría crear un ViewGroup personalizado que dibuje esa forma sobre cada niño anulando el método onDraw.

Ivagarz
fuente
4

Cree un archivo xml en su carpeta dibujable con el siguiente código. (El nombre del archivo que creé es round_corner.xml)

esquina_ redondeada.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>

Y mantenga esto drawablecomo backgroundpara la vista en la que desea mantener el borde de la esquina redondeada. Dejémoslo por unLinearLayout

    <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
fuente
3

siga este tutorial y toda la discusión debajo de él - http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-dered-corners/

De acuerdo con esta publicación escrita por Guy Romain, uno de los desarrolladores líderes de todo el kit de herramientas de la interfaz de usuario de Android, es posible hacer un contenedor (y todas las vistas de sus hijos) con esquinas redondeadas, pero explicó que es demasiado caro (por las actuaciones de problemas de renderizado).

Te recomendaré que vayas de acuerdo con su publicación, y si quieres esquinas redondeadas, implementa las esquinas redondeadas de ImageViewacuerdo con esta publicación. luego, puedes colocarlo dentro de un contenedor con cualquier fondo y obtendrás el efecto que deseas.

eso es lo que hice también eventualmente.

Tal Kanel
fuente
3

Puedes usar un me androidx.cardview.widget.CardViewgusta así:

<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>

O

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>

y dentro de tu diseño

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

        ...

</LinearLayout>
Rahul
fuente
3

El CardViewtrabajó para mí en el API 27 en Android Studio 3.0.1. Se colorPrimaryhizo referencia a él en el res/values/colors.xmlarchivo y es solo un ejemplo. Porque el layout_width 0dpse extenderá hasta el ancho del padre. Tendrá que configurar las restricciones y el ancho / alto según sus necesidades.

<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
fuente
3

Con la Biblioteca de componentes de materiales, la mejor manera de hacer un Viewcon esquinas redondeadas es usar el MaterialShapeDrawable.

Cree un ShapeAppearanceModel con esquinas redondeadas personalizadas:

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

Crea un MaterialShapeDrawable:

MaterialShapeDrawable shapeDrawableLL1 = new MaterialShapeDrawable(shapeAppearanceModeLL1);

Si desea aplicar también una superposición de elevación para el tema oscuro, use esto:

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

Opcional: aplicar al shapeDrawable un color de fondo y un trazo

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

Finalmente, aplique shapeDrawable como fondo en su LinearLayout(u otra vista):

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

ingrese la descripción de la imagen aquí

Gabriele Mariotti
fuente
2

Diferencia con la respuesta de Jaap van Hengstum:

  1. Utilice BitmapShader en lugar de máscara de mapa de bits.
  2. Cree un mapa de bits solo una 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
fuente
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
fuente
1

El enlace del tutorial que proporcionó parece sugerir que debe establecer las propiedades layout_width y layout_height de sus elementos secundarios en match_parent.

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
danielcooperxyz
fuente
1

Para crear una imagen de esquina redondeada 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)

o si desea usarlo en un archivo xml:

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

en style.xml agregue esto:

<style name="circleImageView" parent="">
      <item name="cornerFamily">rounded</item>
      <item name="cornerSize">10%</item>
</style>
Erfan Eghterafi
fuente
0

pruebe esta propiedad con su diseño lineal, ayudará a las
herramientas: contexto = ". su actividad"


fuente
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
fuente
0

Por si quieres doblar alguna esquina concreta.

fun setCorners() {
        
        val mOutlineProvider = object : ViewOutlineProvider() {
            override fun getOutline(view: View, outline: Outline) {

                val left = 0
                val top = 0;
                val right = view.width
                val bottom = view.height
                val cornerRadiusDP = 16f
                val cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, cornerRadiusDP, resources.displayMetrics).toInt()

                // all corners
                outline.setRoundRect(left, top, right, bottom, cornerRadius.toFloat())

                /* top corners
                outline.setRoundRect(left, top, right, bottom+cornerRadius, cornerRadius.toFloat())*/

                /* bottom corners
                outline.setRoundRect(left, top - cornerRadius, right, bottom, cornerRadius.toFloat())*/

                /* left corners
                outline.setRoundRect(left, top, right + cornerRadius, bottom, cornerRadius.toFloat())*/

                /* right corners
                outline.setRoundRect(left - cornerRadius, top, right, bottom, cornerRadius.toFloat())*/

                /* top left corner
                outline.setRoundRect(left , top, right+ cornerRadius, bottom + cornerRadius, cornerRadius.toFloat())*/

                /* top right corner
                outline.setRoundRect(left - cornerRadius , top, right, bottom + cornerRadius, cornerRadius.toFloat())*/

                /* bottom left corner
                outline.setRoundRect(left, top - cornerRadius, right + cornerRadius, bottom, cornerRadius.toFloat())*/

                /* bottom right corner
                outline.setRoundRect(left - cornerRadius, top - cornerRadius, right, bottom, cornerRadius.toFloat())*/

            }
        }

        myView.apply {
            outlineProvider = mOutlineProvider
            clipToOutline = true
        }
    }
Timur Panzhiev
fuente
-1

Use la forma en xml con rectángulo, establezca la propiedad de radio inferior o superior como desee, luego aplique ese xml como fondo a su vista ... o ... use degradados para hacerlo desde el código.

Pratik Deogade
fuente
Ya lo hice, pero ¿quiero saber si hay un método mejor?
Zach
El solicitante ya mencionó haber probado este enfoque en su pregunta.
Michael Krause