it-swarm-es.com

¿Cómo hacer el diseño con esquinas redondeadas ..?

¿Cómo puedo hacer un diseño con esquinas redondeadas? Quiero aplicar esquinas redondeadas a mi LinearLayout.

421
Addy

1: Define layout_bg.xml in drawables:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <solid Android:color="#FFFFFF"/>
    <stroke Android:width="3dp" Android:color="#B1BCBE" />
    <corners Android:radius="10dp"/>
    <padding Android:left="0dp" Android:top="0dp" Android:right="0dp" Android:bottom="0dp" />
</shape>

2: Agregue layout_bg.xml como fondo a su diseño

Android:background="@drawable/layout_bg"
870
Gaurav Arora

Para API 21+, usar vistas de clip

El recorte de esquema redondeado se agregó a la clase View en la API 21. Vea este documento de capacitación o esta referencia para más información.

Esta característica incorporada hace que las esquinas redondeadas sean muy fáciles de implementar. Funciona en cualquier vista o diseño y admite el recorte adecuado.

Esto es lo que hay que hacer:

  • Cree una forma redondeada dibujable y establézcala como fondo de su vista: Android:background="@drawable/round_outline"
  • De acuerdo con la documentación, entonces todo lo que necesita hacer es esto: Android:clipToOutline="true"

Desafortunadamente, parece que hay un error y este atributo XML actualmente no se reconoce. Afortunadamente, podemos configurar el recorte en Java:

  • En su actividad o fragmento: View.setClipToOutline(true)

Lo que parece:

enter image description here

Nota especial sobre ImageViews

setClipToOutline() solo funciona cuando el fondo de la Vista se establece en una forma dibujable. Si existe esta forma de fondo, la vista trata el contorno del fondo como los bordes para fines de recorte y sombreado.

Esto significa que si desea redondear las esquinas en un ImageView con setClipToOutline(), su imagen debe provenir de Android:src en lugar de Android:background (ya que el fondo se usa para la forma redondeada). Si DEBE usar el fondo para configurar su imagen en lugar de src, puede usar esta solución de vista anidada:

  • Cree un diseño exterior con su fondo configurado a su forma dibujable
  • Envuelva ese diseño alrededor de su ImageView (sin relleno)
  • El ImageView (incluyendo cualquier otra cosa en el diseño) ahora se recortará a la forma redondeada del diseño exterior.
85
hungryghost

Aquí hay una copia de un archivo XML para crear un dibujo con un fondo blanco, un borde negro y esquinas redondeadas:

 <?xml version="1.0" encoding="UTF-8"?> 
    <shape xmlns:Android="http://schemas.Android.com/apk/res/Android"> 
        <solid Android:color="#ffffffff"/>    

        <stroke Android:width="3dp"
                Android:color="#ff000000"
                />

        <padding Android:left="1dp"
                 Android:top="1dp"
                 Android:right="1dp"
                 Android:bottom="1dp"
                 /> 

        <corners Android:bottomRightRadius="7dp" Android:bottomLeftRadius="7dp" 
         Android:topLeftRadius="7dp" Android:topRightRadius="7dp"/> 
    </shape>

guárdelo como un archivo xml en el directorio dibujable, úselo como si usara cualquier fondo dibujable (icono o archivo de recursos) usando su nombre de recurso (R.drawable.your_xml_name)

56
kyogs

He hecho de esta manera:

Compruebe la captura de pantalla:

 Relative layout Background

Cree drawable archivo nombrado con custom_rectangle.xml en drawable folder:

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

    <solid Android:color="@Android:color/white" />

    <corners Android:radius="10dip" />

    <stroke
        Android:width="1dp"
        Android:color="@Android:color/white" />

</shape>

Ahora aplique Fondo del rectángulo on Vista :

mView.setBackground(R.drawlable.custom_rectangle);

Hecho

25
Hiren Patel

Utilice CardView en la biblioteca de soporte de Android v7. Aunque es un poco pesado, resuelve todos los problemas y es bastante fácil. No como el método de fondo dibujable establecido, podría recortar subvistas con éxito.

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.CardView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:card_view="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    card_view:cardBackgroundColor="@Android:color/transparent"
    card_view:cardCornerRadius="5dp"
    card_view:cardElevation="0dp"
    card_view:contentPadding="0dp">
    <YOUR_LINEARLAYOUT_HERE>
</Android.support.v7.widget.CardView>
24
Evan JIANG

Creo que una mejor manera de hacerlo es fusionar 2 cosas:

  1. haga un mapa de bits del diseño, como se muestra aquí .

  2. haga un dibujo redondeado del mapa de bits, como se muestra aquí

  3. establece el dibujable en una imageView.

Esto manejará los casos que otras soluciones no han podido resolver, como tener contenido que tiene esquinas.

Creo que también es un poco más compatible con GPU, ya que muestra una sola capa en lugar de 2.

La única forma mejor de hacerlo es hacer una vista totalmente personalizada, pero es mucho código y puede llevar mucho tiempo. Creo que lo que sugerí aquí es lo mejor de ambos mundos.

Aquí hay un fragmento de cómo se puede hacer:

RoundedCornersDrawable.Java

/**
 * shows a bitmap as if it had rounded corners. based on :
 * http://rahulswackyworld.blogspot.co.il/2013/04/Android-drawables-with-rounded_7.html
 * easy alternative from support library: RoundedBitmapDrawableFactory.create( ...) ; 
 */
public class RoundedCornersDrawable extends BitmapDrawable {

    private final BitmapShader bitmapShader;
    private final Paint p;
    private final RectF rect;
    private final float borderRadius;

    public RoundedCornersDrawable(final Resources resources, final Bitmap bitmap, final float borderRadius) {
        super(resources, bitmap);
        bitmapShader = new BitmapShader(getBitmap(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        final Bitmap b = getBitmap();
        p = getPaint();
        p.setAntiAlias(true);
        p.setShader(bitmapShader);
        final int w = b.getWidth(), h = b.getHeight();
        rect = new RectF(0, 0, w, h);
        this.borderRadius = borderRadius < 0 ? 0.15f * Math.min(w, h) : borderRadius;
    }

    @Override
    public void draw(final Canvas canvas) {
        canvas.drawRoundRect(rect, borderRadius, borderRadius, p);
    }
}

CustomView.Java

public class CustomView extends ImageView {
    private View mMainContainer;
    private boolean mIsDirty=false;

    // TODO for each change of views/content, set mIsDirty to true and call invalidate

    @Override
    protected void onDraw(final Canvas canvas) {
        if (mIsDirty) {
            mIsDirty = false;
            drawContent();
            return;
        }
        super.onDraw(canvas);
    }

    /**
     * draws the view's content to a bitmap. code based on :
     * http://nadavfima.com/Android-snippet-inflate-a-layout-draw-to-a-bitmap/
     */
    public static Bitmap drawToBitmap(final View viewToDrawFrom, final int width, final int height) {
        // Create a new bitmap and a new canvas using that bitmap
        final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(bmp);
        viewToDrawFrom.setDrawingCacheEnabled(true);
        // Supply measurements
        viewToDrawFrom.measure(MeasureSpec.makeMeasureSpec(canvas.getWidth(), MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(canvas.getHeight(), MeasureSpec.EXACTLY));
        // Apply the measures so the layout would resize before drawing.
        viewToDrawFrom.layout(0, 0, viewToDrawFrom.getMeasuredWidth(), viewToDrawFrom.getMeasuredHeight());
        // and now the bmp object will actually contain the requested layout
        canvas.drawBitmap(viewToDrawFrom.getDrawingCache(), 0, 0, new Paint());
        return bmp;
    }

    private void drawContent() {
        if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0)
            return;
        final Bitmap bitmap = drawToBitmap(mMainContainer, getMeasuredWidth(), getMeasuredHeight());
        final RoundedCornersDrawable drawable = new RoundedCornersDrawable(getResources(), bitmap, 15);
        setImageDrawable(drawable);
    }

}

EDITAR: encontró una alternativa agradable, basada en "RoundKornersLayouts" de la biblioteca . Tenga una clase que se utilizará para todas las clases de diseño que desee ampliar, para redondear:

//based on https://github.com/JcMinarro/RoundKornerLayouts
class CanvasRounder(cornerRadius: Float, cornerStrokeColor: Int = 0, cornerStrokeWidth: Float = 0F) {
    private val path = Android.graphics.Path()
    private lateinit var rectF: RectF
    private var strokePaint: Paint?
    var cornerRadius: Float = cornerRadius
        set(value) {
            field = value
            resetPath()
        }

    init {
        if (cornerStrokeWidth <= 0)
            strokePaint = null
        else {
            strokePaint = Paint()
            strokePaint!!.style = Paint.Style.STROKE
            strokePaint!!.isAntiAlias = true
            strokePaint!!.color = cornerStrokeColor
            strokePaint!!.strokeWidth = cornerStrokeWidth
        }
    }

    fun round(canvas: Canvas, drawFunction: (Canvas) -> Unit) {
        val save = canvas.save()
        canvas.clipPath(path)
        drawFunction(canvas)
        if (strokePaint != null)
            canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, strokePaint)
        canvas.restoreToCount(save)
    }

    fun updateSize(currentWidth: Int, currentHeight: Int) {
        rectF = Android.graphics.RectF(0f, 0f, currentWidth.toFloat(), currentHeight.toFloat())
        resetPath()
    }

    private fun resetPath() {
        path.reset()
        path.addRoundRect(rectF, cornerRadius, cornerRadius, Path.Direction.CW)
        path.close()
    }

}

Luego, en cada una de sus clases de diseño personalizadas, agregue un código similar a este:

class RoundedConstraintLayout : ConstraintLayout {
    private lateinit var canvasRounder: CanvasRounder

    constructor(context: Context) : super(context) {
        init(context, null, 0)
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init(context, attrs, 0)
    }

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
        init(context, attrs, defStyle)
    }

    private fun init(context: Context, attrs: AttributeSet?, defStyle: Int) {
        val array = context.obtainStyledAttributes(attrs, R.styleable.RoundedCornersView, 0, 0)
        val cornerRadius = array.getDimension(R.styleable.RoundedCornersView_corner_radius, 0f)
        val cornerStrokeColor = array.getColor(R.styleable.RoundedCornersView_corner_stroke_color, 0)
        val cornerStrokeWidth = array.getDimension(R.styleable.RoundedCornersView_corner_stroke_width, 0f)
        array.recycle()
        canvasRounder = CanvasRounder(cornerRadius,cornerStrokeColor,cornerStrokeWidth)
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            setLayerType(FrameLayout.LAYER_TYPE_SOFTWARE, null)
        }
    }

    override fun onSizeChanged(currentWidth: Int, currentHeight: Int, oldWidth: Int, oldheight: Int) {
        super.onSizeChanged(currentWidth, currentHeight, oldWidth, oldheight)
        canvasRounder.updateSize(currentWidth, currentHeight)
    }

    override fun draw(canvas: Canvas) = canvasRounder.round(canvas) { super.draw(canvas) }

    override fun dispatchDraw(canvas: Canvas) = canvasRounder.round(canvas) { super.dispatchDraw(canvas) }

}

Si desea admitir atributos, use esto como está escrito en la biblioteca:

<resources>
  <declare-styleable name="RoundedCornersView">
      <attr name="corner_radius" format="dimension"/>
      <attr name="corner_stroke_width" format="dimension"/>
      <attr name="corner_stroke_color" format="color"/>
  </declare-styleable>
</resources>

Otra alternativa, que podría ser más fácil para la mayoría de los usos: use MaterialCardView. Permite personalizar las esquinas redondeadas, el color y el ancho del trazo y la elevación.

Ejemplo:

<FrameLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android" xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools" Android:layout_width="match_parent"
    Android:layout_height="match_parent" Android:clipChildren="false" Android:clipToPadding="false"
    tools:context=".MainActivity">

    <com.google.Android.material.card.MaterialCardView
        Android:layout_width="100dp" Android:layout_height="100dp" Android:layout_gravity="center"
        app:cardCornerRadius="8dp" app:cardElevation="8dp" app:strokeColor="#f00" app:strokeWidth="2dp">

        <ImageView
            Android:layout_width="match_parent" Android:layout_height="match_parent" Android:background="#0f0"/>

    </com.google.Android.material.card.MaterialCardView>

</FrameLayout>

Y el resultado:

 enter image description here

Tenga en cuenta que hay un pequeño problema de artefactos en los bordes del trazo (deja algunos píxeles del contenido allí), si lo usa. Puede notarlo si hace zoom. He informado sobre este problema aquí .

20
android developer

Prueba esto...

1.create drawable xml (custom_layout.xml):

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

<solid Android:color="#FFFFFF" />

<stroke
    Android:width="2dp"
    Android:color="#FF785C" />

<corners Android:radius="10dp" />

</shape>

2.add su vista de fondo

Android:background="@drawable/custom_layout"
10

Una mejor manera de hacerlo sería:

background_activity.xml

<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:gravity="fill">
        <color Android:color="@color/black"/>
    </item>
    <item>
        <shape Android:gravity="fill">
            <solid Android:color="@color/white"/>
            <corners Android:radius="10dip"/>
            <padding Android:left="0dip" Android:top="0dip" Android:right="0dip" Android:bottom="0dip" />
        </shape>
    </item>
</layer-list>

Esto funcionará también debajo de API 21, y le dará algo como esto:

 Result


Si está dispuesto a hacer un poco más de esfuerzo, más control, utilice Android.support.v7.widget.CardView con su atributo cardCornerRadius (y establezca el atributo elevation en 0dp para deshacerse de cualquier sombra paralela que acompañe con el CardView). Además, esto funcionará desde el nivel de API tan bajo como 15.

5
Abdul Wasae

Si desea redondear su diseño, es mejor utilizar CardView, ya que ofrece muchas características para hacer que el diseño sea hermoso.

<Android.support.v7.widget.CardView
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    card_view:cardCornerRadius="5dp">
      <LinearLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content">

            <TextView
                Android:layout_width="0dp"
                Android:layout_height="wrap_content"
                Android:layout_weight=".3"
                Android:text="@string/quote_code"
                Android:textColor="@color/white"
                Android:textSize="@dimen/text_head_size" />
      </LinearLayout>
</Android.support.v7.widget.CardView>

Con esta card_view: cardCornerRadius = "5dp", puedes cambiar el radio.

5
Farruh Habibullaev

Utilice CardView para obtener bordes redondeados para cualquier diseño. Use card_view: cardCornerRadius = "5dp" para que cardview obtenga bordes de diseño redondeados.

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
  xmlns:card_view="http://schemas.Android.com/apk/res-auto"
  Android:layout_width="match_parent"
  Android:layout_height="match_parent"
  Android:orientation="vertical">

      <Android.support.v7.widget.CardView
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        card_view:cardCornerRadius="5dp">
          <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:orientation="horizontal"
                Android:padding="15dp"
                Android:weightSum="1">

                <TextView
                    Android:layout_width="0dp"
                    Android:layout_height="wrap_content"
                    Android:layout_weight=".3"
                    Android:text="@string/quote_code"
                    Android:textColor="@color/white"
                    Android:textSize="@dimen/text_head_size" />

                <TextView
                    Android:layout_width="0dp"
                    Android:layout_height="wrap_content"
                    Android:layout_weight=".7"
                    Android:text="@string/quote_details"
                    Android:textColor="@color/white"
                    Android:textSize="@dimen/text_head_size" />
            </LinearLayout>
       </Android.support.v7.widget.CardView>
   </LinearLayout>
4
vishnuc156
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <solid Android:color="#FFFFFF"/>
    <stroke Android:width="3dip" Android:color="#B1BCBE" />
    <corners Android:radius="10dip"/>
    <padding Android:left="3dip" Android:top="3dip" Android:right="3dip" Android:bottom="3dip" />
</shape>

@David, simplemente coloque el mismo valor de relleno que el trazo, para que el borde pueda ser visible, sin importar el tamaño de la imagen

3
escar

El mejor y más simple método sería utilizar card_background drawable en su diseño. Esto también sigue las pautas de diseño de material de Google. Solo incluye esto en tu LinearLayout:

Android:background="@drawable/card_background"

Agregue esto a su directorio dibujable y asígnele el nombre card_background.xml :

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item>
        <shape Android:shape="rectangle">
            <solid Android:color="#BDBDBD"/>
            <corners Android:radius="5dp"/>
        </shape>
    </item>

    <item
        Android:left="0dp"
        Android:right="0dp"
        Android:top="0dp"
        Android:bottom="2dp">
        <shape Android:shape="rectangle">
            <solid Android:color="#ffffff"/>
            <corners Android:radius="5dp"/>
        </shape>
    </item>
</layer-list>
3
Divyanshu Maithani

Función para establecer el radio de la esquina programáticamente

static void setCornerRadius(GradientDrawable drawable, float topLeft,
        float topRight, float bottomRight, float bottomLeft) {
    drawable.setCornerRadii(new float[] { topLeft, topLeft, topRight, topRight,
            bottomRight, bottomRight, bottomLeft, bottomLeft });
}

static void setCornerRadius(GradientDrawable drawable, float radius) {
    drawable.setCornerRadius(radius);
}

Utilizando

GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setColor(Color.GREEN);
setCornerRadius(gradientDrawable, 20f);
//or setCornerRadius(gradientDrawable, 20f, 40f, 60f, 80f); 

view.setBackground(gradientDrawable);
3
Phan Van Linh

Tomé la respuesta de @gauravsapiens con mis comentarios en el interior para darle una comprensión razonable de lo que afectarán los parámetros.

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

    <!-- Background color -->
    <solid Android:color="@color/white" />

    <!-- Stroke around the background, width and color -->
    <stroke Android:width="4dp" Android:color="@color/drop_shadow"/>

    <!-- The corners of the shape -->
    <corners Android:radius="4dp"/>

    <!-- Padding for the background, e.g the Text inside a TextView will be 
    located differently -->
    <padding Android:left="10dp" Android:right="10dp" 
             Android:bottom="10dp" Android:top="10dp" />

</shape>

Si solo buscas crear una forma que redondee las esquinas, eliminar el relleno y el trazo serán suficientes. Si elimina el sólido, en efecto, habrá creado esquinas redondeadas sobre un fondo transparente.

Para ser perezoso, he creado una forma debajo, que es solo un fondo blanco sólido con esquinas redondeadas, ¡disfrútalo! :)

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

    <!-- Background color -->
    <solid Android:color="@color/white" />

    <!-- The corners of the shape -->
    <corners Android:radius="4dp"/>

</shape>
1
ZooMagic
Create your xml in drawable, layout_background.xml

 <?xml version="1.0" encoding="utf-8"?>
        <shape xmlns:Android="http://schemas.Android.com/apk/res/Android" >
        <solid Android:color="@color/your_colour" />
        <stroke
            Android:width="2dp"
            Android:color="@color/your_colour" />
        <corners Android:radius="10dp" />      
        </shape>
 <--width, color, radius should be as per your requirement-->

Finally in your layout.xml file write below line

 Android:background="@drawable/layout_background"
0
Bapusaheb Shinde
 <shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:padding="@dimen/_10sdp"
Android:shape="rectangle">

<solid Android:color="@color/header" />

<corners
    Android:bottomLeftRadius="@dimen/_5sdp"
    Android:bottomRightRadius="@dimen/_5sdp"
    Android:topLeftRadius="@dimen/_5sdp"
    Android:topRightRadius="@dimen/_5sdp" />
0
keval patel