How to make Android look with rounded corners

I am trying to pretend in an android with rounded edges. The solution I have found so far is to define a shape with rounded corners and use it as the background of this view.

Here is what I did, define as shown below

<padding android:top="2dp" android:bottom="2dp"/> <corners android:bottomRightRadius="20dp" android:bottomLeftRadius="20dp" android:topLeftRadius="20dp" android:topRightRadius="20dp"/> 

Now I used this as a background for my layout as shown below

 <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:clipChildren="true" android:background="@drawable/rounded_corner"> 

This works fine, I see the view has rounded edges.

But there are many other child views in my layout. Say ImageView or MapView. When I place the ImageView inside the above layout, the corners of the image are not cropped / cropped, but filled.

I saw other workarounds to get it working, as described here here .

But is there a way to set rounded corners for a view, and all of its child views are contained in this main view, which is rounded corners?

Thank.

+73
android android-layout android-view android-shape
Sep 27 '14 at 12:41
source share
16 answers

Another approach is to create your own layout class, as shown below. This layout first displays its contents on the screen bitmap, masks the off-screen bitmap with a rounded rectangle, and then draws the off-screen bitmap on the actual canvas.

I tried and it seems to work (at least for my simple test record). This, of course, will affect performance compared to the usual layout.

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

Use this as a regular layout:

 <com.example.RoundedCornerLayout android:layout_width="200dp" android:layout_height="200dp"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/test"/> <View android:layout_width="match_parent" android:layout_height="100dp" android:background="#ff0000" /> </com.example.RoundedCornerLayout> 
+111
05 Oct '14 at 8:57
source share

Or you can use android.support.v7.widget.CardView like this:

 <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="wrap_content" android:layout_height="wrap_content" card_view:cardBackgroundColor="@color/white" card_view:cardCornerRadius="4dp"> <!--YOUR CONTENT--> </android.support.v7.widget.CardView> 
+49
May 13 '16 at 1:45
source share

shape.xml

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

and inside your layout

 <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:clipChildren="true" android:background="@drawable/shape"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/your image" android:background="@drawable/shape"> </LinearLayout> 
+40
Oct 03 '14 at 6:46
source share

If you are having trouble adding touch listeners to the layout. Use this layout as the parent layout.

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

as

 <?xml version="1.0" encoding="utf-8"?> <com.example.view.RoundedCornerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:id="@+id/patentItem" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingRight="20dp"> ... your child goes here </RelativeLayout> </com.example.view.RoundedCornerLayout> 
+16
Feb 08 '16 at 10:04 on
source share

Jaap van Hengstum's answer works fine, but I think it is expensive, and if we apply this method on a button, for example, the touch effect will be lost, since the view is displayed as a bitmap.

For me, the best method and the simplest one is to use a mask in a view, for example:

 @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); } 
+15
Dec 12 '16 at 10:26
source share

Create an XML file called round.xml in the drawable folder and paste the contents:

 <?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:width=".05dp" android:color="#d2d2d2" /> <corners android:topLeftRadius="5dp" android:topRightRadius="5dp" android:bottomRightRadius="5dp" android:bottomLeftRadius="5dp"/> </shape> 

then use round.xml as the background for any element. Then it will give you rounded corners.

+10
04 Oct '14 at 5:00 a.m.
source share

In Android L, you can simply use View.setClipToOutline to get this effect. In previous versions, it was not possible to simply trim the contents of a random ViewGroup of a particular shape.

You will have to think about something that will give you a similar effect:

  • If you only need rounded corners in ImageView, you can use a shader to “paint over” the image on top of the shape that you use as the background. Take a look at this library for an example.

  • If you really need all the children to be circumcised, maybe you can take a different look at your layout? One with the background of the color you are using, with a round “hole” in the middle? You could actually create a custom ViewGroup that draws this form above each child that overrides the onDraw method.

+9
Oct 03 '14 at 3:55
source share

CardView worked for me in API 27 in Android Studio 3.0.1. colorPrimary referenced in res/values/colors.xml and is just an example. For layout_width of 0dp it will stretch to the width of the parent. You will need to adjust the limits and width / height to suit your needs.

 <android.support.v7.widget.CardView android:id="@+id/cardView" android:layout_width="0dp" android:layout_height="200dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" app:cardCornerRadius="4dp" app:cardBackgroundColor="@color/colorPrimary"> <!-- put your content here --> </android.support.v7.widget.CardView> 
+3
Dec 03 '17 at 6:20
source share

Create an XML file in the Drawable folder using the following code. (The name of the file I created is rounded_corner.xml)

rounded_corner.xml

  <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-- view background color --> <solid android:color="#a9c5ac" > </solid> <!-- view border color and width --> <stroke android:width="3dp" android:color="#1c1b20" > </stroke> <!-- If you want to add some padding --> <padding android:left="4dp" android:top="4dp" android:right="4dp" android:bottom="4dp" > </padding> <!-- Here is the corner radius --> <corners android:radius="10dp" > </corners> </shape> 

And leave this as the background for the view for which you want to keep the border of the rounded corner. Leave it for LinearLayout

  <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/rounded_corner" android:layout_centerInParent="true"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Hi, This layout has rounded corner borders ..." android:gravity="center" android:padding="5dp"/> </LinearLayout> 
+3
Nov 08 '18 at 9:35
source share

follow this guide and all the discussion under it - http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/

according to this entry, written by Guy Romain, one of the leading developers of the entire Android UI toolkit, you can create a container (and all its children's views) with rounded corners, but he explained that it is too expensive (from rendering tasks).

I will recommend you go according to your post, and if you want rounded corners, then use ImageView rounded corners according to this post. then you can put it in a container with any background, and you will get the effect that you need.

which I, too, end up with.

+2
Oct 03 '14 at 18:29
source share
 public class RoundedCornerLayout extends FrameLayout { private double mCornerRadius; public RoundedCornerLayout(Context context) { this(context, null, 0); } public RoundedCornerLayout(Context context, AttributeSet attrs) { this(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(); setLayerType(View.LAYER_TYPE_SOFTWARE, null); } public double getCornerRadius() { return mCornerRadius; } public void setCornerRadius(double cornerRadius) { mCornerRadius = cornerRadius; } @Override public void draw(Canvas canvas) { int count = canvas.save(); final Path path = new Path(); path.addRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), (float) mCornerRadius, (float) mCornerRadius, Path.Direction.CW); canvas.clipPath(path, Region.Op.REPLACE); canvas.clipPath(path); super.draw(canvas); canvas.restoreToCount(count); } } 
+2
Jun 16 '16 at 12:16
source share

The proposed tutorial link assumes that you need to set the layout_width and layout_height properties, match_parent for your children.

 <ImageView android:layout_width="match_parent" android:layout_height="match_parent"> 
+1
Sep 27 '14 at 12:53 on
source share

Difference from Jaap van Hengstum's answer:

  • Use BitmapShader instead of a mask bitmap.
  • Create a raster image only once.
 public class RoundedFrameLayout extends FrameLayout { private Bitmap mOffscreenBitmap; private Canvas mOffscreenCanvas; private BitmapShader mBitmapShader; private Paint mPaint; private RectF mRectF; public RoundedFrameLayout(Context context) { super(context); init(); } public RoundedFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); init(); } public RoundedFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { setWillNotDraw(false); } @Override public void draw(Canvas canvas) { if (mOffscreenBitmap == null) { mOffscreenBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888); mOffscreenCanvas = new Canvas(mOffscreenBitmap); mBitmapShader = new BitmapShader(mOffscreenBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setShader(mBitmapShader); mRectF = new RectF(0f, 0f, canvas.getWidth(), canvas.getHeight()); } super.draw(mOffscreenCanvas); canvas.drawRoundRect(mRectF, 8, 8, mPaint); } } 
+1
Sep 17 '15 at 11:04
source share

try this property with a linear layout, this will help tools: context = "youractivity"

0
Sep 27 '14 at 13:22
source share
 public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { Bitmap roundedBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap .getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(roundedBitmap); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); final float roundPx = pixels; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return roundedBitmap; } 
0
May 9 '16 at 11:32
source share

Use the form in xml with the rectangle.set property of the lower or upper radius as you want. Then apply this xml as background for ur view .... or ... use gradients to do this from code.

-one
Sep 30 '14 at 18:16
source share



All Articles