Drawing LinearLayout with rounded corners

瘦欲@ 提交于 2019-12-09 08:41:12

问题


I'm trying to implement a LinearLayout subclass that draws itself with rounded corners. From my research, I set setWillNotDraw(false) and overridden onDraw() to draw a rounded rectangle in the canvas:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    int sc = canvas.saveLayer(0, 0, getWidth(), getHeight(), drawPaint, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
            | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
    canvas.drawRoundRect(bounds, mCornerRadius, mCornerRadius, roundPaint);
    canvas.restoreToCount(sc);
}

where:

drawPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
drawPaint.setColor(0xffffffff);
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
roundPaint.setColor(0xffffffff);

DST_IN seems the correct option here (according to the APIDemos example), but the area that should be transparent (the rounded one) has instead a black background, and the corners of the children are still visible. This is the result on a Galaxy Nexus with Android 4.2.2:

Any hints?

EDIT: Here is what I'd like to achieve, sorry for the crudeness of photoshopping :)

EDIT 2: I added to GitHub an example runnable project: https://github.com/venator85/RoundClippingLayout

Thanks ;)


回答1:


Not quite the same : Romain Guy did a blog post about cropping corners on images using bitmap shaders.. Not sure if you would want to extend the same thing.

http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/




回答2:


Try this,

Layout:-

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout 
        android:id="@+id/linearLayout"
        android:layout_width="300dp"
        android:gravity="center"
        android:layout_height="300dp"
        android:layout_centerInParent="true"
        android:background="@drawable/rounded_edge">
        <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="foo" />
    </LinearLayout>
</RelativeLayout>

Shape(Drawable):-rounded_edge.xml

<shape 
        xmlns:android="http://schemas.android.com/apk/res/android">
            <solid 
                android:color="@android:color/darker_gray">
            </solid>
            <stroke 
                 android:width="0dp" 
                 android:color="#424242">
            </stroke>
            <corners 
                 android:topLeftRadius="100dip"
                 android:topRightRadius="100dip"
                 android:bottomLeftRadius="100dip"
                 android:bottomRightRadius="100dip">
            </corners>
        </shape>



回答3:


I could achieve a LinearLayout with rounded corners like this.

Steps:

1. Create a custom layout

public class RoundedLayout extends LinearLayout {
    private RectF rect;
    private Paint paint;

    public RoundedLayout(Context context) {
        super(context);
        init();
    }
    public RoundedLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        rect = new RectF(0.0f, 0.0f, getWidth(), getHeight());
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.parseColor("#7EB5D6"));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);           
        canvas.drawRoundRect(rect, 20, 20, paint);
    }
}

2. Use it in the main layout like this

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="#336699" >

    <com.example.rounded.RoundedLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:padding="30dp"
        android:background="@android:color/transparent" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="foo" />

    </com.example.rounded.RoundedLayout>    

</LinearLayout>



回答4:


Try this !! taken from this post

Add the following into a file (say customshape.xml) and then place it in (res/drawable/customshape.xml)

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
 android:shape="rectangle"> 
 <gradient 
     android:startColor="#SomeGradientBeginColor"
     android:endColor="#SomeGradientEndColor" 
     android:angle="270"/> 

<corners 
     android:bottomRightRadius="7dp" 
     android:bottomLeftRadius="7dp" 
     android:topLeftRadius="7dp" 
     android:topRightRadius="7dp"/> 
</shape> 

Once you are done with creating this file, just set the background in one of the following ways:

Through Code:

yourObject.setBackgroundResource(R.drawable.customshape);

Or through XML, just add the following attribute to the container (ex: LinearLayout or to any fields):

android:background="@drawable/customshape"



回答5:


How about...

myLayout.setBackgroundResource(R.drawable.my_rounded_drawable);

Then...

my_rounded_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="#FFFFFFFF" />
            <stroke android:width="1dip" android:color="#FF000000" />
            <corners android:radius="10dp" />
        </shape>
    </item>
</selector>



回答6:


Instead of trying to cut the corners off your layout, why not place a Drawable on top of it as a sort of frame that matches the color of your background?




回答7:


[EDIT: looks like this will be added in L: https://developer.android.com/preview/material/views-shadows.html#clip, which allows you to clip a view to the shape of a rectanglular, circular, or round rectangular drawable.]

I just tried for a really long time to do this myself, and came upon this answer that suggests it is not possible, since the View class is based on Rect class. I just checked the source and from the comments it looks like that's still the case.

Motorola is releasing the Moto 360 (Android Wear watch with round face) later this summer, so maybe there will be updates to the framework that allow for Views with shapes other than rectangles.



来源:https://stackoverflow.com/questions/15906206/drawing-linearlayout-with-rounded-corners

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!