我试图在android中创建一个圆角边的视图.到目前为止我找到的解决方案是定义一个带圆角的形状,并将其用作该视图的背景.
这就是我所做的,定义一个drawable,如下所示
现在我用它作为我的布局的背景如下
这很好用,我可以看到视图有圆角.
但我的布局中有许多其他子视图说一个ImageView或一个MapView.当我在上面的布局中放置一个ImageView时,图像的角不会被剪裁/裁剪,而是显示为满.
我已经看到了其他解决方法,使它像这里解释的那样工作.
但有没有一种方法可以为视图设置圆角,并且所有子视图都包含在具有圆角的主视图中?
谢谢.
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>
或者您可以这样使用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>
如果在向布局添加触摸侦听器时遇到问题.将此布局用作父布局.
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>
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); }
在Android L中,您将能够使用View.setClipToOutline来获得该效果.在以前的版本中,无法仅以某种形状剪切随机ViewGroup的内容.
你将不得不考虑一些可以产生类似效果的东西:
如果您只需要在ImageView中使用圆角,则可以使用着色器在您用作背景的形状上"绘制"图像.看一下这个库就可以了.
如果你真的需要剪掉每个孩子,也许你可以对你的布局进行另一种观察?一个背景是你正在使用的颜色,中间是一个圆形的"洞"?实际上,您可以创建一个自定义ViewGroup,在覆盖onDraw方法的每个子项上绘制该形状.
另一种方法是创建一个自定义布局类,如下所示.此布局首先将其内容绘制到屏幕外位图,使用圆角矩形屏蔽屏幕外位图,然后在实际画布上绘制屏幕外位图.
我尝试了它似乎工作(至少对我的简单测试用例).与常规布局相比,它当然会影响性能.
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>
在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作为项目的背景.然后它将给出圆角