Como fazer o layout com cantos arredondados ..?

517

Como posso fazer um layout com cantos arredondados? Quero aplicar cantos arredondados ao meu LinearLayout.

Addy
fonte
criar uma forma que pode ser desenhada com canto e depois definir como plano de fundo .. onde está o problema?
Stinepike:
você só precisa definir uma imagem arredondada como pano de fundo de layout de forma make outra coisa, como disse no primeiro comentário
SilentKiller
você só precisa procurar mais Então ... você vai encontrar um monte de asnwers ..
Pankaj Kumar
os cantos são obscurecidos por mim
filthy_wizard

Respostas:

1030

1: Defina layout_bg.xml nos 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: adicione layout_bg.xmlcomo plano de fundo ao seu layout

android:background="@drawable/layout_bg"
Gaurav Arora
fonte
194
Isso não funciona. como você definiu, é o plano de fundo; portanto, o conteúdo substitui os cantos arredondados e, se você tiver um conteúdo desenhado nos cantos, não os verá arredondados.
desenvolvedor Android
22
Quase sempre, meu conteúdo nunca cobre os cantos. Isso funciona perfeitamente.
David JY Tang
2
Como você evita o erro Element shape doesn't have the required attribute android:layout_height?
Lorenz
2
Element shape doesn't have the required attribute android:layout_heightO motivo pelo qual o erro foi mostrado porque layout_bg.xml não estava dentro da pasta desenhável.
Atul
8
@ nhouser9: na verdade, é mais como "Funciona, mas esteja avisado de que o seu primeiro plano / conteúdo pode aparecer nos cantos". Portanto, dependendo do caso de uso, pode funcionar 100%. Fico feliz que a resposta não tenha tantas votações negativas porque é útil, e fico feliz que o comentário tenha cem votações positivas porque é fácil identificar a limitação com esta solução. Melhor dos dois mundos.
Benoit Duffez 01/01
125

Para a API 21 ou superior, use as visualizações de clipe

O recorte de contorno arredondado foi adicionado à Viewclasse na API 21. Consulte este documento de treinamento ou esta referência para obter mais informações.

Esse recurso incorporado facilita a implementação de cantos arredondados. Funciona em qualquer visualização ou layout e suporta recorte adequado.

Aqui está o que fazer:

  • Crie uma gaveta de forma arredondada e defina-a como o plano de fundo da sua exibição: android:background="@drawable/round_outline"
  • De acordo com a documentação, tudo o que você precisa fazer é o seguinte: android:clipToOutline="true"

Infelizmente, parece haver um bug e esse atributo XML atualmente não é reconhecido. Felizmente, podemos definir o recorte em Java:

  • Na sua atividade ou fragmento: View.setClipToOutline(true)

O que isso parece:

insira a descrição da imagem aqui

Nota especial sobre o ImageViews

setClipToOutline()só funciona quando o plano de fundo da vista é definido como uma forma desenhável. Se essa forma de plano de fundo existir, o View tratará o contorno do plano de fundo como bordas para fins de recorte e sombreamento.

Isso significa que, se você deseja arredondar os cantos em um ImageView setClipToOutline(), sua imagem deve ser originada em android:srcvez de android:background(já que o fundo é usado para a forma arredondada). Se você DEVE usar o plano de fundo para definir sua imagem em vez de src, pode usar esta solução alternativa de visualizações aninhadas:

  • Crie um layout externo com o plano de fundo definido como sua forma desenhável
  • Enrole esse layout em torno do seu ImageView (sem preenchimento)
  • O ImageView (incluindo qualquer outra coisa no layout) agora será cortado na forma arredondada do layout externo.
fome
fonte
9
Não funciona em API inferior a 21. Não posso esperar até que eu só posso apoiar API 21.
startoftext
O uso de 'setClipToOutline' funciona, mas também remove o próprio quadro (o drawable que você usa para o fundo). Existe alguma maneira de evitar isso?
desenvolvedor android
Você leu minha nota sobre o uso em src=@drawable...vez de background=@drawable? Você pode fazer isso ou aninhar seu ImageView dentro de uma exibição de contêiner que contém o contorno da forma.
hungryghost
9
Todo mundo comenta esse bug - ele tem quase três anos e não mostra sinais de conserto a qualquer momento nesta década. Vamos pressionar um pouco.
Josh Hansen
Como não esse bug ser ainda fixo
P Fuster
74

Aqui está uma cópia de um arquivo XML para criar um drawable com fundo branco, borda preta e cantos arredondados:

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

salve-o como um arquivo xml no diretório drawable. Use-o como se fosse qualquer plano de fundo drawable (ícone ou arquivo de recurso) usando seu nome de recurso (R.drawable.your_xml_name)

kyogs
fonte
5
Adorava a possibilidade de arredondar cantos específicos
Mercury
1
Esta resposta é praticamente a resposta acima. A única mudança real aqui é a definição de cada raio de canto, e dada a sua o mesmo valor para cada canto eu teria escrito em uma linha em vez disso: <corners android:radius="7dp" />:)
ZooMagic
esta é a melhor resposta para mim, uma vez que abrange a disponibilidade de arredondamento cantos específicos ... bom trabalho, funciona 100%
Mahmoud Ayman
Os cantos do ImageView não são arredondados (cortados), como resolvo isso?
Primož Kralj
Ainda funciona em setembro de 2019. Bom.
Nikolas Rieble 19/09/19
36

Use o CardView na biblioteca de suporte do Android v7. Embora seja um pouco pesado, resolve todos os problemas e é fácil. Não como o método de segundo plano desenhável, ele pode cortar subvisões com ê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>
Evan JIANG
fonte
2
Muito melhor para todos que podem "pagar" do que qualquer outra coisa. Confunde-me que uma coisa tão básica não é parte de vistas padrão do Android, sendo um grampo em CSS para quase qualquer navegador web
Ben Philipp
29

Eu fiz assim:

Verificar captura de tela:

Layout relativo

Crie um arquivo drawable nomeado com custom_rectangle.xmlna pasta drawable :

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

Agora aplique o plano de fundo do retângulo no modo de exibição :

mView.setBackground(R.drawlable.custom_rectangle);

Feito

Hiren Patel
fonte
14
Isso não funciona. como você definiu, é o plano de fundo; portanto, o conteúdo substitui os cantos arredondados e, se você tiver um conteúdo desenhado nos cantos, não os verá arredondados.
desenvolvedor android
25

Eu acho que a melhor maneira de fazer isso é mesclar duas coisas:

  1. faça um bitmap do layout, como mostrado aqui .

  2. faça um drawable arredondado do bitmap, como mostrado aqui

  3. defina o drawable em um imageView.

Isso resolverá casos que outras soluções não conseguiram resolver, como conteúdo com cantos.

Eu acho que também é um pouco mais amigável à GPU, pois mostra uma única camada em vez de 2.

A única maneira melhor é fazer uma visualização totalmente personalizada, mas isso é muito código e pode levar muito tempo. Eu acho que o que sugeri aqui é o melhor dos dois mundos.

Aqui está um trecho de como isso pode ser feito:

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);
    }

}

EDIT: encontrou uma boa alternativa, com base na biblioteca "RoundKornersLayouts" . Tenha uma classe que será usada para todas as classes de layout que você deseja estender, para ser arredondada:

//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()
    }

}

Em seguida, em cada uma das suas classes de layout personalizadas, adicione código semelhante 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) }

}

Se você deseja suportar atributos, use isto como está escrito na 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>

Outra alternativa, que pode ser mais fácil para a maioria dos usos: use MaterialCardView. Permite personalizar os cantos arredondados, a cor e a largura do traço e a elevação.

Exemplo:

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

E o resultado:

insira a descrição da imagem aqui

Observe que há um pequeno problema de artefato nas bordas do traçado (deixa alguns pixels do conteúdo), se você o usar. Você pode perceber se aumentar o zoom. Eu relatei sobre esse problema aqui .

EDIT: parece estar corrigido, mas não no IDE. Relatado aqui .

desenvolvedor android
fonte
Graças para a montagem de esta resposta incrível, ele tem me movendo na direção certa, mas eu poderia usar alguma ajuda com um problema muito relacionada aqui stackoverflow.com/questions/25877515/...
Will Thomson
Isso gera erro, pois não há construtor padrão disponível no ImageView.
Anuj
Essa resposta deve ser aceita. Em vez de lógica plana, você desceu e encontrou uma solução incrível. Isso também resolve os problemas mencionados nos comentários para outras respostas. Obrigado pelo seu esforço e talvez você possa corrigir uma classe totalmente funcional e compartilhá-la via github. Eu acho que isso pode ajudar muitas pessoas.
Arda Kara
@ Senhor Você acha que eu deveria? Eu vou pensar sobre isso. Por enquanto, você pode ver os outros repositórios que eu criei
desenvolvedor android
Como grande parte disso, você pode experimentá-lo. Btw autofittextview parece muito legal.
Arda Kara
10

Tente isso ...

1.criar xml desenhável (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. adicione o seu plano de exibição

android:background="@drawable/custom_layout"
Silambarasan Poonguti
fonte
Assim como escrevi acima sobre uma solução semelhante: Isso não funciona. como você definiu, é o plano de fundo; portanto, o conteúdo substitui os cantos arredondados e, se você tiver um conteúdo desenhado nos cantos, não os verá arredondados.
desenvolvedor android
9

Se você deseja arredondar o layout, é melhor usar o CardView, pois ele oferece muitos recursos para deixar o design bonito.

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

Com este card_view: cardCornerRadius = "5dp", você pode alterar o raio.

Farruh Habibullaev
fonte
5

O melhor e mais simples método seria usar o card_background drawable em seu layout. Isso também segue as diretrizes de design de material do Google. Basta incluir isso no seu LinearLayout:

android:background="@drawable/card_background"

Adicione isso ao seu diretório drawable e chame -o de 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>
Divyanshu Maithani
fonte
5

Use o CardView para obter bordas arredondadas para qualquer layout. Use card_view: cardCornerRadius = "5dp" para cardview obter bordas de layout arredondadas.

<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>
vishnuc156
fonte
CardView da biblioteca support.v7, você pode usar a partir da API7 ou superior.
Nikita G.
5

Uma maneira melhor de fazer isso seria:

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>

Isso também funcionará abaixo da API 21 e fornecerá algo assim:

Resultado


Se você estiver disposto a fazer um pouco mais de esforço para ter um controle melhor, use-o android.support.v7.widget.CardViewcom seu cardCornerRadiusatributo (e defina o elevationatributo 0dppara se livrar de qualquer sombra que acompanha o cardView). Além disso, isso funcionará no nível da API tão baixo quanto 15.

Abdul Wasae
fonte
Se o conteúdo se encaixar no plano de fundo, ele será substituído. Ele realmente não se encaixa na forma que você definiu.
desenvolvedor android
Você quer dizer outra visão? Você pode atualizar o código para mostrar o que você quer dizer? A idéia é que os cantos arredondados não colocariam área preta. Nos cantos, deve haver cores transparentes.
desenvolvedor android
Oh, eu recebo sua pergunta agora. Eu acho que para isso, você pode se contentar com uma pequena margem fixa sobre o seu conteúdo
Abdul Wasae
Mas, então, o conteúdo não será cortado na forma que você escolher, porque as margens fixas são retangulares e não de acordo com a forma que você escolher.
desenvolvedor android
5

Função para o raio do canto programado

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);
}

Usando

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

view.setBackground(gradientDrawable);
Phan Van Linh
fonte
4
<?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, basta colocar preenchimento com o mesmo valor que o traçado, para que a borda fique visível, sem tamanho de imagem

paezinc
fonte
3

Eu levei a resposta @gauravsapiens com meus comentários para dentro para lhe dar uma compreensão razoável do efeito dos 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>

Se você está apenas procurando criar uma forma que contorne os cantos, remover o preenchimento e o traço serve. Se você também remover o sólido, criará cantos arredondados em um fundo transparente.

Por uma questão de ser preguiçoso, criei uma forma por baixo, que é apenas um fundo branco sólido com cantos arredondados - divirta-se! :)

<?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>
ZooMagic
fonte
3

Crie seu xml no 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-->

e depois adicione isso no seu layout.xml

 android:background="@drawable/layout_background"
Bapusaheb Shinde
fonte
2

Com a Biblioteca de componentes de material, você pode usar o MaterialShapeDrawablepara desenhar formas personalizadas .

Basta colocar o LinearLayout no seu layout xml:

<LinearLayout
    android:id="@+id/linear_rounded"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    ..>

    <!-- content ..... -->

</LinearLayout>

Em seguida, no seu código, você pode aplicar a ShapeAppearanceModel. Algo como:

float radius = getResources().getDimension(R.dimen.default_corner_radius);

LinearLayout linearLayout= findViewById(R.id.linear_rounded);
ShapeAppearanceModel shapeAppearanceModel = new ShapeAppearanceModel()
    .toBuilder()
    .setAllCorners(CornerFamily.ROUNDED,radius)
    .build();

MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable(shapeAppearanceModel);
//Fill the LinearLayout with your color
shapeDrawable.setFillColor(ContextCompat.getColorStateList(this,R.color.secondaryLightColor));


ViewCompat.setBackground(linearLayout,shapeDrawable);

insira a descrição da imagem aqui

Nota :: requer a versão 1.1.0 da biblioteca de componentes do material.

Gabriele Mariotti
fonte
1
 <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" />

Keval Patel
fonte