如何制作圆角布局..?

How to make layout with rounded corners..?

提问人:Addy 提问时间:4/23/2013 最后编辑:Gabriele MariottiAddy 更新时间:4/15/2022 访问量:717605

问:

如何制作圆角布局?我想将圆角应用于我的 .LinearLayout

Android XML 图像 布局 android-shapedrawable

评论

1赞 SilentKiller 4/23/2013
您只需要将圆角图像设置为布局的背景,否则可以按照第一条评论中的说法进行形状
0赞 Pankaj Kumar 4/23/2013
你只需要搜索 SO...你会发现很多 asnwers ..
0赞 filthy_wizard 11/3/2017
角落对我来说是模糊的
1赞 Ucdemir 9/27/2020
谷歌有新框架,新技术更好 Jetpack Compose

答:

1266赞 Gaurav Arora 4/23/2013 #1

1:在可绘制对象中定义layout_bg.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="3dp" android:color="#B1BCBE" />
    <corners android:radius="10dp"/>
    <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>

2:将背景添加到布局中layout_bg.xml

android:background="@drawable/layout_bg"

评论

239赞 android developer 5/14/2014
这是行不通的。正如您设置的那样,它是背景,因此内容会覆盖圆角,如果您有在圆角上绘制的内容,则不会看到它们被圆角。
27赞 David J. Y. Tang 7/25/2014
几乎总是,我的内容从不覆盖角落。这非常有效。
2赞 Lorenz 7/31/2015
如何避免错误?Element shape doesn't have the required attribute android:layout_height
2赞 Atul 9/2/2016
Element shape doesn't have the required attribute android:layout_height显示错误的原因layout_bg.xml因为 不在可绘制文件夹中。
11赞 Benoit Duffez 1/2/2018
@nhouser9:实际上,它更像是“它有效,但请注意,您的前景/内容可能会在角落里画画”。因此,根据用例,它可能 100% 有效。我很高兴答案没有那么多反对票,因为它很有用,我很高兴评论有一百个赞成票,因为很容易发现这个解决方案的局限性。两全其美。
97赞 kyogs 4/23/2013 #2

下面是一个 XML 文件的副本,用于创建具有白色背景、黑色边框和圆角的可绘制对象:

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

将其保存为 drawable 目录中的 xml 文件, 使用它就像使用任何可绘制背景(图标或资源文件)一样使用它,使用其资源名称 (R.drawable.your_xml_name)

评论

7赞 Mercury 1/26/2017
喜欢圆角的可能性
1赞 ZooMagic 1/12/2018
这个答案几乎就是上面的答案。这里唯一真正的变化是每个角半径的定义,鉴于每个角的值相同,我会把它写在一行中::)<corners android:radius="7dp" />
0赞 Mahmoud Ayman 5/9/2018
这对我来说是最好的答案,因为它涵盖了圆角的可用性......干得好,工作 100%
1赞 c0dehunter 4/9/2019
ImageView 的边角没有圆角(剪裁),我该如何解决?
30赞 Hiren Patel 4/23/2013 #3

我是这样做的:

检查屏幕截图:

Relative layout Background

drawable 文件夹中创建名为 的 drawable 文件:custom_rectangle.xml

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

现在在视图上应用矩形背景

mView.setBackground(R.drawlable.custom_rectangle);

评论

19赞 android developer 5/14/2014
这是行不通的。正如您设置的那样,它是背景,因此内容会覆盖圆角,如果您有在圆角上绘制的内容,则不会看到它们被圆角。
31赞 android developer 5/14/2014 #4

我认为更好的方法是合并两件事:

  1. 制作布局的位图,如下所示

  2. 从位图中创建一个圆角可绘制对象,如下所示

  3. 在 imageView 上设置可绘制对象。

这将处理其他解决方案无法解决的情况,例如内容有角落。

我认为它对 GPU 也更友好一些,因为它显示的是单层而不是 2 层。

唯一更好的方法是制作一个完全自定义的视图,但这需要大量的代码,并且可能需要很多时间。我认为我在这里的建议是两全其美的。

以下是如何完成的片段:

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

自定义视图:.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);
    }

}

编辑:找到了一个不错的替代方案,基于“RoundKornersLayouts”库。有一个类,该类将用于要扩展的所有布局类,并进行舍入:

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

}

然后,在每个自定义布局类中,添加类似于以下内容的代码:

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

}

如果您希望支持属性,请使用库上写的以下内容:

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

另一种选择,对于大多数用途来说可能更容易: 使用 MaterialCardView 。它允许自定义圆角、描边颜色和宽度以及高度。

例:

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

结果:

enter image description here

请注意,如果您使用它,则在描边的边缘存在轻微的伪影问题(在那里留下内容的一些像素)。如果你放大,你可以注意到它。我已经在这里报告了这个问题。

编辑:似乎已修复,但不在IDE上。在这里报告。

评论

0赞 Will Thomson 9/17/2014
感谢您整理这个很棒的答案,它让我朝着正确的方向前进,但我可以在这里有一个非常相关的问题 stackoverflow.com/questions/25877515/ 使用一些帮助......
0赞 Anuj 12/9/2014
这会产生错误,因为 ImageView 中没有可用的默认构造函数。
0赞 Arda Kara 1/5/2015
这应该是公认的答案。你不是扁平的逻辑,而是去找到一个很棒的解决方案。这也解决了您在对其他答案的评论中提到的问题。感谢您的努力,也许您可以纠正一个功能齐全的类并通过 github 共享它。我认为它可能会帮助太多人。
0赞 android developer 1/5/2015
@Senhor你认为我应该这样做吗?我会考虑的。现在,您可以在此处查看我创建的其他存储库:github.com/AndroidDeveloperLB?tab=repositories
0赞 Arda Kara 1/5/2015
作为完成的很大一部分,您可以尝试一下。顺便说一句,autofittextview看起来真的很酷。
12赞 Silambarasan Poonguti 9/17/2014 #5

试试这个...

1.创建可绘制的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.添加视图背景

android:background="@drawable/custom_layout"

评论

1赞 android developer 11/16/2017
正如我上面写的类似解决方案:这不起作用。正如您设置的那样,它是背景,因此内容会覆盖圆角,如果您有在圆角上绘制的内容,则不会看到它们被圆角。
4赞 paezinc 3/17/2015 #6
<?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,只需将填充值与描边相同,因此无论图像大小如何,边框都可见

185赞 hungryghost 6/7/2015 #7

对于 API 21+,请使用剪辑视图

在 API 21 中,已将圆角轮廓剪裁添加到类中。有关详细信息,请参阅此培训文档或此参考View

这种内置功能使圆角非常容易实现。它适用于任何视图或布局,并支持适当的剪辑。

这是要做的事情:

  • 创建一个可绘制的圆角形状,并将其设置为视图的背景:android:background="@drawable/round_outline"
  • 剪辑以在代码中概述:setClipToOutline(true)

文档曾经说过您可以设置 XML,但这个错误现在终于解决了,文档现在正确地指出您只能在代码中执行此操作。android:clipToOutline="true"

它看起来像什么:

examples with and without clipToOutline

关于 ImageView 的特别说明

setClipToOutline()仅当视图的背景设置为可绘制的形状时才有效。如果存在此背景形状,则“视图”会将背景的轮廓视为用于剪裁和阴影的边框。

这意味着,如果要使用 ,则图像必须来自而不是 (因为 background 用于圆角形状)。如果必须使用 background 而不是 src 来设置图像,则可以使用以下嵌套视图解决方法:setClipToOutline()android:srcandroid:background

  • 创建一个外部布局,其背景设置为可绘制的形状
  • 将该布局环绕在 ImageView 周围(不带填充)
  • ImageView(包括布局中的任何其他内容)现在将被裁剪到外部布局的圆角形状。

评论

10赞 startoftext 1/14/2016
不适用于小于 21 的 API。等不及我只能支持 API 21。
0赞 android developer 11/16/2017
使用“setClipToOutline”可以工作,但它也会删除框架本身(用于背景的可绘制对象)。有什么方法可以避免这种情况吗?
0赞 hungryghost 11/22/2017
你有没有读过我关于使用代替 ?您可以这样做,也可以将 ImageView 嵌套在保存形状轮廓的容器视图中。src=@drawable...background=@drawable
17赞 Josh Hansen 3/16/2018
每个人都对这个错误发表评论---它已经快三年了,而且这十年来没有修复的迹象。让我们施加一些压力。
1赞 JediBurrell 9/8/2018
@FebinMathew 你不能。
7赞 Divyanshu Maithani 7/15/2015 #8

最好和最简单的方法是在布局中使用card_background可绘制对象。这也遵循了 Google 的材料设计指南。只需将其包含在 LinearLayout 中即可:

android:background="@drawable/card_background"

将它添加到您的可绘制目录中,并将其命名为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>
53赞 Evan JIANG 7/29/2015 #9

在 android v7 支持库中使用 CardView。 虽然它有点重,但它解决了所有问题,而且很容易。 与设置可绘制背景方法不同,它可以成功剪辑子视图。

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

评论

4赞 Ben Philipp 4/20/2018
对于每个“负担得起”它的人来说,这比其他任何事情都要好得多。令我感到困惑的是,这样一个基本的东西不是标准 Android 视图的一部分,几乎是任何 Web 浏览器的 CSS 的主要内容
6赞 vishnuc156 4/5/2016 #10

使用 CardView 获取任何布局的圆角边缘。 对 cardview 使用 card_view:cardCornerRadius=“5dp” 来获取圆角布局边缘。

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

评论

0赞 Nikita G. 5/31/2016
support.v7 库中的 CardView,可以从 API7 或更高版本使用。
14赞 Farruh Habibullaev 12/13/2016 #11

如果你想使你的布局四舍五入,最好使用CardView,它提供了许多功能来使设计美观。

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

使用此 card_view:cardCornerRadius=“5dp”,您可以更改半径。

5赞 Abdul Wasae 4/17/2017 #12

更好的方法是:

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>

这也将在 API 21 以下工作,并为您提供如下内容:

Result


如果您愿意付出更多的努力,更好地控制,那么请与其属性一起使用(并将属性设置为以摆脱 cardView 附带的任何投影)。此外,这将在低至 15 的 API 级别下工作。android.support.v7.widget.CardViewcardCornerRadiuselevation0dp

评论

1赞 android developer 11/16/2017
如果内容适合背景,它将覆盖它。它并没有真正剪裁到您设置的形状。
0赞 android developer 11/16/2017
你是说另一种观点?你能更新代码以显示你的意思吗?这个想法是圆角不会放置黑色区域。在拐角处,应该有透明的颜色。
0赞 Abdul Wasae 11/17/2017
哦,我现在明白你的问题了。我想为此,您可以在内容上使用少量的固定边距
0赞 android developer 11/18/2017
但是,内容不会被剪切成你选择的形状,因为固定边距是矩形的,而不是根据你选择的形状。
5赞 Bapusaheb Shinde 9/26/2017 #13

在 drawable 中创建您的 xml,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-->

然后,将其添加到您的layout.xml

 android:background="@drawable/layout_background"
4赞 Keval Patel 11/20/2017 #14
 <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" />

7赞 Linh 12/21/2017 #15

以编程方式设置拐角半径的功能

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

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

view.setBackground(gradientDrawable);
4赞 ZooMagic 1/12/2018 #16

我已经用我的评论@gauravsapiens答案,让您合理地了解参数将产生什么影响。

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

如果您只是想创建一个圆角的形状,那么去除填充和笔触就可以了。如果同时删除实体,则实际上会在透明背景上创建圆角。

为了懒惰,我在下面创建了一个形状,它只是一个带有圆角的纯白色背景 - 尽情享受吧!:)

<?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>
10赞 Gabriele Mariotti 12/23/2019 #17

通过材质组件库,您可以使用 MaterialShapeDrawable 绘制自定义形状

只需将 LinearLayout 放在 xml 布局中:

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

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

</LinearLayout>

然后,在代码中,您可以应用 .像这样:ShapeAppearanceModel

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

enter image description here

注意::它需要 1.1.0 版本的材料组件库。

评论

2赞 ror 10/10/2020
这是我的观察,希望可以帮助某人。如果您为上述设置了错误的半径(过高,例如,如果控制高度为 40,则为 56 而不是 20),则上述角无论如何都会显示正确,但仅限于 api 21。对于 api 19,它们将非常混乱:)除非您输入正确的半径。
0赞 LGFox 12/22/2022
@ror,我在 API26 上也有同样的行为。原来我设置了.删除 clipToOutline 后,一切都恢复正常。clipToOutline=true
17赞 Abdul Basit Rishi 9/14/2020 #18

第 1 步:在 drawables 文件夹中定义bg_layout.xml,并将以下代码放入其中。

第 2 步:将该bg_layout.xml作为背景添加到您的布局中,完成。

    <?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid
        android:color="#EEEEEE"/> <!--your desired colour for solid-->

    <stroke
        android:width="3dp"
        android:color="#EEEEEE" /> <!--your desired colour for border-->

    <corners
        android:radius="50dp"/> <!--shape rounded value-->

</shape>
0赞 Ali Rezaiyan 2/7/2021 #19

您可以使用自定义视图来执行此操作,例如 RoundAppBar 和 RoundBottomAppBar 这里 a 用于画布。pathclipPath

Round Corner View

2赞 Yokich 5/18/2021 #20

我来晚了一点,但这仍然是一个问题。因此,我编写了一组用于数据绑定的 OutlineProviders 和 BindingAdapters,使您能够从 xml 中剪切角。

注意:带轮廓的剪裁不支持不同尺寸的角!

在这个 stackoverflow 帖子上用代码写了一个详细的回复

您将通过代码 + 绑定适配器获得什么:

<androidx.constraintlayout.widget.ConstraintLayout
    clipRadius="@{@dimen/some_radius}"
    clipBottomLeft="@{@dimen/some_radius}"
    clipBottomRight="@{@dimen/some_radius}"
    clipTopLeft="@{@dimen/some_radius}"
    clipTopRight="@{@dimen/some_radius}"
    clipCircle="@{@bool/clip}"

这使您能够将视图裁剪为圆形、所有角、一个方向(左、上、右、下)或单角的圆角。

评论

1赞 Yokich 5/18/2021
如果你只想要一个圆润的背景,这是矫枉过正的,你最好使用可绘制的xml。但是,如果您想在不突出图像的情况下使布局的角落变圆,这就是方法。
3赞 ucMedia 11/30/2021 #21

如果您想要的只是一个简单的圆角矩形,请长话短说。

float r=8;
ShapeDrawable shape = 
   new ShapeDrawable (new RoundRectShape(new float[] { r, r, r, r, r, r, r, r },null,null));
shape.getPaint().setColor(Color.RED);
view.setBackground(shape);

android rounded rectangle shape

  • 前两个浮点数用于左上角(其余对应顺时针对应)。

有关更多详细信息,请阅读此答案