首页 文章

如何制作圆角布局..?

提问于
浏览
392

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

17 回答

  • 25

    使用CardView可以获得任何布局的圆角边缘 . 使用 card_view:cardCornerRadius="5dp" for 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>
    
  • 21

    For API 21+, Use Clip Views

    已修改的轮廓剪辑已添加到API 21中的 View 类 . 有关详细信息,请参阅training doc或此reference .

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

    Here's What To Do:

    • 创建一个圆形的drawable并将其设置为视图的背景: android:background="@drawable/round_outline"

    • 根据文档,您需要做的就是: android:clipToOutline="true"

    不幸的是,似乎有a bug,目前无法识别此XML属性 . 幸运的是,我们可以在Java中设置剪辑:

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

    What It Looks Like:

    enter image description here

    Special Note About ImageViews

    setClipToOutline() 仅在查看's background is set to a shape drawable. If this background shape exists, View treats the background' s轮廓作为剪裁和阴影用途的边框时有效 .

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

    • 创建外部布局,其背景设置为可绘制的形状

    • 在ImageView周围换行布局(没有填充)

    • ImageView(包括布局中的任何其他内容)现在将被剪裁为外部布局的圆形形状 .

  • 52

    最好和最简单的方法是在布局中使用 card_background drawable . 这也符合Google的材料设计指南 . 只需在你的LinearLayout中包含它:

    android:background="@drawable/card_background"
    

    将其添加到您的drawable目录并将其命名为 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
    <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" />
    
  • 4

    这是一个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>
    

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

  • 10

    更好的方法是:

    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


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

  • 0
    <?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,只需将填充值与笔划相同,因此边框可见,无图像大小

  • 67

    如果您想使您的布局四舍五入,最好使用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

    我已经将@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>
    
  • 3

    Inteml的xml

    android:background="@drawable/layout_shape"
    

    使用(代码中):

    getDialog().getWindow().setBackgroundDrawableResource(R.drawable.layout_shape)
    
  • 3

    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>
    

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

    android:background="@drawable/layout_bg"
    
  • 0

    在drawable,layout_background.xml中创建xml

    <solid android:color="@color/your_colour" />
    
        <stroke
    
            android:width="2dp"
            android:color="@color/your_colour" />
    
        <corners android:radius="10dp" />
    
        </shape>
    

    < - 宽度,颜色,半径应符合您的要求 - >

    最后在你的layout.xml文件中写下以下行

    android:background="@drawable/layout_background"
    
  • 0

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

    • 制作布局的位图,如here所示 .

    • 从位图中创建一个圆形的drawable,如图所示here

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

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

    编辑:基于"RoundKornersLayouts" library找到了一个不错的选择 . 有一个将用于所有要扩展的布局类的类,要进行舍入:

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

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

  • 1

    试试这个...

    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.添加您的视图背景

    android:background="@drawable/custom_layout"
    
  • 3

    在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>
    
  • 800

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

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

    我这样做了:

    检查截图:

    Relative layout Background

    drawable 文件夹中创建以 custom_rectangle.xml 命名的 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>
    

    现在在 View 上申请 Rectangle background

    mView.setBackground(R.drawlable.custom_rectangle);
    

    Done

相关问题