如何制作圆角布局..?

Add*_*ddy 465 xml layout android image

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

Gau*_*ora 942

1:在drawables中定义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>
Run Code Online (Sandbox Code Playgroud)

2:添加layout_bg.xml为布局的背景

android:background="@drawable/layout_bg"
Run Code Online (Sandbox Code Playgroud)

  • 这不起作用.正如您设置的那样,它是背景,因此内容会覆盖圆角,如果您有内容绘制角落,则不会看到它们被舍入. (172认同)
  • 几乎总是,我的内容从不覆盖角落.这非常有效. (17认同)
  • @ nhouser9:实际上它更像是"它有效,但要注意你的前景/内容可能会在角落里画出来".因此,根据用例,它可能100%工作.我很高兴答案没有那么多的downvotes,因为它很有用,我很高兴评论有一百个赞成票,因为很容易发现这个解决方案的局限性.两全其美. (4认同)
  • 你如何避免错误`元素形状没有所需的属性android:layout_height`? (2认同)
  • `元素形状没有必需的属性 android:layout_height` 显示错误的原因是因为 layout_bg.xml 不在 drawable 文件夹中。 (2认同)
  • 当像这样的错误答案获得如此多的选票时,事情就变得非常错误 (2认同)

hun*_*ost 107

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

ViewAPI 21中的类中添加了圆形轮廓修剪.有关详细信息,请参阅此培训文档或此参考.

这种内置功能使圆角非常容易实现.它适用于任何视图或布局,并支持正确剪切.

这是做什么的:

  • 创建一个圆形的drawable并将其设置为视图的背景: android:background="@drawable/round_outline"
  • 根据文档,那么您需要做的就是: android:clipToOutline="true"

不幸的是,似乎存在一个错误,目前无法识别此XML属性.幸运的是,我们可以在Java中设置剪辑:

  • 在您的活动或片段中: View.setClipToOutline(true)

它看起来像什么:

在此输入图像描述

关于ImageViews的特别注意事项

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

这意味着如果要在ImageView上对角进行圆角处理setClipToOutline(),则必须使用图像android:src而不是android:background(因为背景用于圆角形状).如果必须使用背景来设置图像而不是src,则可以使用此嵌套视图解决方法:

  • 创建一个外部布局,其背景设置为您的形状可绘制
  • 在ImageView周围包裹该布局(没有填充)
  • ImageView(包括布局中的任何其他内容)现在将被剪裁为外部布局的圆形形状.

  • 不适用于低于21的API.不能等到我只能支持API 21. (9认同)
  • 每个人都对这个错误发表评论---它已经快三年了,而且在这个十年的任何时候都没有任何修复的迹象.让我们施加压力. (8认同)
  • @FebinMathew 你不能。 (2认同)

kyo*_*ogs 65

这是一个XML文件的副本,用于创建具有白色背景,黑色边框和圆角的drawable:

 <?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>
Run Code Online (Sandbox Code Playgroud)

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

  • 喜欢圆角特定角落的可能性 (5认同)

小智 32

在android v7支持库中使用CardView.虽然它有点重,但它解决了所有问题,而且很容易.与set drawable background方法不同,它可以成功剪辑子视图.

<?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>
Run Code Online (Sandbox Code Playgroud)

  • 对于每个能够“负担”得起的人来说,要比其他任何事情都要好得多。让我感到困惑的是,这种基本的东西不是标准Android视图的一部分,而是几乎所有Web浏览器的CSS必备内容 (2认同)

Hir*_*tel 26

我这样做了:

检查截图:

相对布局背景

创建绘制的名为文件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>
Run Code Online (Sandbox Code Playgroud)

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

mView.setBackground(R.drawlable.custom_rectangle);
Run Code Online (Sandbox Code Playgroud)

完成

  • 这不起作用.正如您设置的那样,它是背景,因此内容会覆盖圆角,如果您有内容绘制角落,则不会看到它们被舍入. (14认同)

and*_*per 21

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

  1. 使布局的位图,如图所示这里.

  2. 做一个圆形绘制从位图,如图所示这里

  3. 在imageView上设置drawable.

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

我认为它对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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

编辑:基于"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()
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,在每个自定义布局类中,添加与此类似的代码:

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

}
Run Code Online (Sandbox Code Playgroud)

如果您希望支持属性,请使用库中所写的:

<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>
Run Code Online (Sandbox Code Playgroud)

另一种替代方案,对于大多数用途可能更容易:使用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>
Run Code Online (Sandbox Code Playgroud)

结果如下:

在此输入图像描述

请注意,如果您使用它,笔划的边缘会出现轻微的瑕疵问题(在那里留下一些内容的像素).如果你放大,你可以注意到它.我在这里报告了这个问题.


Abd*_*shi 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>
Run Code Online (Sandbox Code Playgroud)


Sil*_*uti 10

试试这个...

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>
Run Code Online (Sandbox Code Playgroud)

2.添加您的视图背景

android:background="@drawable/custom_layout"
Run Code Online (Sandbox Code Playgroud)


Gab*_*tti 9

随着材料零件库,你可以使用MaterialShapeDrawable绘制自定义形状

只需将 LinearLayout 放在您的 xml 布局中:

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

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

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

然后在您的代码中,您可以应用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);
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

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

  • 这是我的观察,希望可以帮助别人。如果你为上面设置了错误的半径(过高,比如 56 而不是 20,如果控件高度为 40),上面的角无论如何都会显示正确,但仅从 api 21 开始。对于 api 19,它们会非常混乱向上:)除非您输入正确的半径。 (2认同)

Div*_*ani 7

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

android:background="@drawable/card_background"
Run Code Online (Sandbox Code Playgroud)

将此添加到您的可绘制目录并将其命名为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>
Run Code Online (Sandbox Code Playgroud)


Far*_*aev 6

如果您想使布局四舍五入,则最好使用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>
Run Code Online (Sandbox Code Playgroud)

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


vis*_*156 5

使用CardView可以获取任何布局的圆角边缘。使用card_view:cardCornerRadius =“ 5dp”进行cardview可获得圆形的布局边缘。

<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>
Run Code Online (Sandbox Code Playgroud)


Abd*_*sae 5

更好的方法是:

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>
Run Code Online (Sandbox Code Playgroud)

这也适用于API 21,并给你这样的东西:

结果


如果你愿意更多努力更好地控制,那么使用android.support.v7.widget.CardView它的cardCornerRadius属性(并设置elevation属性来0dp摆脱任何随附的带有cardView的阴影).此外,这将从API级别低至15.


Bap*_*nde 5

在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-->
Run Code Online (Sandbox Code Playgroud)

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

 android:background="@drawable/layout_background"
Run Code Online (Sandbox Code Playgroud)


Pha*_*inh 5

通过编程设置拐角半径的功能

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);
}
Run Code Online (Sandbox Code Playgroud)

使用

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

view.setBackground(gradientDrawable);
Run Code Online (Sandbox Code Playgroud)


Zoo*_*gic 5

我已经接受了 @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>
Run Code Online (Sandbox Code Playgroud)

如果您只是想创建一个圆角形状,那么删除填充和描边就可以了。如果您也删除实体,您实际上会在透明背景上创建圆角。

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

<?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>
Run Code Online (Sandbox Code Playgroud)