如何在android中创建带圆角的视图

 王漻_957 发布于 2022-12-19 14:18

我试图在android中创建一个圆角边的视图.到目前为止我找到的解决方案是定义一个带圆角的形状,并将其用作该视图的背景.

这就是我所做的,定义一个drawable,如下所示



现在我用它作为我的布局的背景如下


这很好用,我可以看到视图有圆角.

但我的布局中有许多其他子视图说一个ImageView或一个MapView.当我在上面的布局中放置一个ImageView时,图像的角不会被剪裁/裁剪,而是显示为满.

我已经看到了其他解决方法,使它像这里解释的那样工作.

但有没有一种方法可以为视图设置圆角,并且所有子视图都包含在具有圆角的主视图中?

谢谢.

7 个回答
  • shape.xml

    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
    
        <solid android:color="#f6eef1" />
    
        <stroke
            android:
            android:color="#000000" />
    
        <padding
            android:bottom="5dp"
            android:left="5dp"
            android:right="5dp"
            android:top="5dp" />
    
        <corners android:radius="5dp" />
    
    </shape>
    

    在你的布局里面

    <LinearLayout
            android:orientation="vertical"
            android:layout_
            android:layout_
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginBottom="10dp"
            android:clipChildren="true"
            android:background="@drawable/shape">
    
            <ImageView
                 android:layout_
                 android:layout_
                 android:src="@drawable/your image"
                 android:background="@drawable/shape">
    
    </LinearLayout>
    

    2022-12-19 14:19 回答
  • 或者您可以这样使用android.support.v7.widget.CardView:

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:layout_
        android:layout_
        card_view:cardBackgroundColor="@color/white"
        card_view:cardCornerRadius="4dp">
    
        <!--YOUR CONTENT-->
    </android.support.v7.widget.CardView>
    

    2022-12-19 14:19 回答
  • 如果在向布局添加触摸侦听器时遇到问题.将此布局用作父布局.

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.RectF;
    import android.graphics.Region;
    import android.util.AttributeSet;
    import android.util.DisplayMetrics;
    import android.util.TypedValue;
    import android.view.View;
    import android.widget.FrameLayout;
    
    public class RoundedCornerLayout extends FrameLayout {
        private final static float CORNER_RADIUS = 6.0f;
        private float cornerRadius;
    
        public RoundedCornerLayout(Context context) {
            super(context);
            init(context, null, 0);
        }
    
        public RoundedCornerLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context, attrs, 0);
        }
    
        public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(context, attrs, defStyle);
        }
    
        private void init(Context context, AttributeSet attrs, int defStyle) {
            DisplayMetrics metrics = context.getResources().getDisplayMetrics();
            cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
    
    
        @Override
        protected void dispatchDraw(Canvas canvas) {
            int count = canvas.save();
    
            final Path path = new Path();
            path.addRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), cornerRadius, cornerRadius, Path.Direction.CW);
            canvas.clipPath(path, Region.Op.REPLACE);
    
            canvas.clipPath(path);
            super.dispatchDraw(canvas);
            canvas.restoreToCount(count);
        }
    
    
    }
    

    <?xml version="1.0" encoding="utf-8"?>
    <com.example.view.RoundedCornerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_
        android:layout_>
    
        <RelativeLayout
            android:id="@+id/patentItem"
            android:layout_
            android:layout_
            android:paddingRight="20dp">
            ... your child goes here
        </RelativeLayout>
    </com.example.view.RoundedCornerLayout>
    

    2022-12-19 14:19 回答
  • Jaap van Hengstum的答案非常有用,但我觉得它很昂贵,如果我们将这个方法应用于Button,例如,由于视图呈现为位图,因此触摸效果会丢失.

    对我来说,最好的方法和最简单的方法是在视图上应用蒙版,如下所示:

    @Override
    protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
        super.onSizeChanged(width, height, oldWidth, oldHeight);
    
        float cornerRadius = <whatever_you_want>;
        this.path = new Path();
        this.path.addRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, Path.Direction.CW);
    }
    
    @Override
    protected void dispatchDraw(Canvas canvas) {
        if (this.path != null) {
            canvas.clipPath(this.path);
        }
        super.dispatchDraw(canvas);
    }
    

    2022-12-19 14:19 回答
  • 在Android L中,您将能够使用View.setClipToOutline来获得该效果.在以前的版本中,无法仅以某种形状剪切随机ViewGroup的内容.

    你将不得不考虑一些可以产生类似效果的东西:

    如果您只需要在ImageView中使用圆角,则可以使用着色器在您用作背景的形状上"绘制"图像.看一下这个库就可以了.

    如果你真的需要剪掉每个孩子,也许你可以对你的布局进行另一种观察?一个背景是你正在使用的颜色,中间是一个圆形的"洞"?实际上,您可以创建一个自定义ViewGroup,在覆盖onDraw方法的每个子项上绘制该形状.

    2022-12-19 14:19 回答
  • 另一种方法是创建一个自定义布局类,如下所示.此布局首先将其内容绘制到屏幕外位图,使用圆角矩形屏蔽屏幕外位图,然后在实际画布上绘制屏幕外位图.

    我尝试了它似乎工作(至少对我的简单测试用例).与常规布局相比,它当然会影响性能.

    package com.example;
    
    import android.content.Context;
    import android.graphics.*;
    import android.util.AttributeSet;
    import android.util.DisplayMetrics;
    import android.util.TypedValue;
    import android.widget.FrameLayout;
    
    public class RoundedCornerLayout extends FrameLayout {
        private final static float CORNER_RADIUS = 40.0f;
    
        private Bitmap maskBitmap;
        private Paint paint, maskPaint;
        private float cornerRadius;
    
        public RoundedCornerLayout(Context context) {
            super(context);
            init(context, null, 0);
        }
    
        public RoundedCornerLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context, attrs, 0);
        }
    
        public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(context, attrs, defStyle);
        }
    
        private void init(Context context, AttributeSet attrs, int defStyle) {
            DisplayMetrics metrics = context.getResources().getDisplayMetrics();
            cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);
    
            paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    
            maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
            maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    
            setWillNotDraw(false);
        }
    
        @Override
        public void draw(Canvas canvas) {
            Bitmap offscreenBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas offscreenCanvas = new Canvas(offscreenBitmap);
    
            super.draw(offscreenCanvas);
    
            if (maskBitmap == null) {
                maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());
            }
    
            offscreenCanvas.drawBitmap(maskBitmap, 0f, 0f, maskPaint);
            canvas.drawBitmap(offscreenBitmap, 0f, 0f, paint);
        }
    
        private Bitmap createMask(int width, int height) {
            Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
            Canvas canvas = new Canvas(mask);
    
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setColor(Color.WHITE);
    
            canvas.drawRect(0, 0, width, height, paint);
    
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);
    
            return mask;
        }
    }
    

    像普通布局一样使用它:

    <com.example.RoundedCornerLayout
        android:layout_
        android:layout_>
    
        <ImageView
            android:layout_
            android:layout_
            android:src="@drawable/test"/>
    
        <View
            android:layout_
            android:layout_
            android:background="#ff0000"
            />
    
    </com.example.RoundedCornerLayout>
    

    2022-12-19 14:19 回答
  • 在drawable文件夹中创建一个xml round.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
      <solid android:color="#FFFFFF" />
      <stroke android: android:color="#d2d2d2" />
      <corners android:topLeftRadius="5dp" android:topRightRadius="5dp" android:bottomRightRadius="5dp" android:bottomLeftRadius="5dp"/>
    </shape>
    

    然后使用round.xml作为项目的背景.然后它将给出圆角

    2022-12-19 14:19 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有