Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android View Clipping

Is there any way to define the clip region of a ViewGroup in android (Honeycomb)? For example, I have a ListView with an image background that has rounded corners. As I scroll through the list, the children stick out past the corners of the background - I would prefer them to clip within the rounded corners. Left: unclipped, Right: clipped

The left image is what it is currently doing, and the right is what I'd like.

I was looking at ClipDrawable, but it seems that this may only be used for progress bars?

Also, I'm trying to do this in a widget. So I cannot use a custom view and override onDraw for masking.

Thank you!

like image 596
Jon Ross Avatar asked Apr 06 '11 23:04

Jon Ross


People also ask

How to add elevation to view in Android?

To set the default (resting) elevation of a view, use the android:elevation attribute in the XML layout. To set the elevation of a view in the code of an activity, use the View. setElevation() method. To set the translation of a view, use the View.

What is Android elevation?

Elevation (Android) Elevation is the relative depth, or distance, between two surfaces along the z-axis. Specifications: Elevation is measured in the same units as the x and y axes, typically in density-independent pixels (dp).


2 Answers

Try subclassing ViewGroup and overriding the OnDraw method as follows, substituting in values for RADIUS_IN_PIXELS:

@Override protected void onDraw(Canvas canvas) {     Path clipPath = new Path();     clipPath.addRoundRect(new RectF(canvas.getClipBounds()), RADIUS_IN_PIXELS, RADIUS_IN_PIXELS, Path.Direction.CW);     canvas.clipPath(clipPath);     super.onDraw(canvas); } 

...and also create a custom drawable like this called something like 'rounded', substituting in YOUR_BACKGROUND_COLOR and RADIUS_IN_DP, making sure to match the rounding of the rectangle in DP to your previous clipping radius in PX:

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android">     <corners android:radius="RADIUS_IN_DP" />     <solid android:color="YOUR_BACKGROUND_COLOR"/> </shape> 

Then you can use that subclass in your layout, adding the lines

android:background="@drawable/rounded" android:clipChildren="true" 

All children will clip to the bounds you specify in the OnDraw() override, and a background will be added based on your 'rounded' drawable.

like image 138
head in the codes Avatar answered Sep 21 '22 16:09

head in the codes


Make sure layout has a background with rounded corners.

Kotlin

layout.outlineProvider = ViewOutlineProvider.BACKGROUND layout.clipToOutline = true 

Java

layout.setOutlineProvider(ViewOutlineProvider.BACKGROUND); layout.setClipToOutline(true); 
like image 22
Marco Avatar answered Sep 21 '22 16:09

Marco