Рисование LinearLayout с закругленными углами

Я пытаюсь реализовать подкласс LinearLayout, который рисуется с закругленными углами. Из моего исследования я установил setWillNotDraw(false) и переопределил onDraw(), чтобы нарисовать округленный прямоугольник в холсте:

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

где:

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 кажется правильным здесь (в соответствии с примером APIDemos), но область, которая должна быть прозрачной (округленная), имеет вместо этого черный фон, а углы детей все еще видны. Это результат работы Galaxy Nexus с Android 4.2.2:

example

Любые подсказки?

EDIT: Вот что я хотел бы добиться, извините за грубость фотошопа:)

enter image description here

EDIT 2: я добавил в GitHub пример запускаемого проекта: https://github.com/venator85/RoundClippingLayout

Спасибо;)

Ответ 2

Попробуйте это,

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>

Форма (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

Как насчет...

myLayout.setBackgroundResource(R.drawable.my_rounded_drawable);

Тогда...

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>

Ответ 4

Я мог бы добиться LinearLayout с закругленными углами, как это.

enter image description here

Шаги:

1. Создать собственный макет

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. Используйте его в основном макете, как это

<?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>

Ответ 5

Попробуй! взятый из этого сообщения

Добавьте следующее в файл (скажем, customhape.xml), а затем поместите его в (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> 

Как только вы закончите создание этого файла, просто установите фон одним из следующих способов:

Через код:

yourObject.setBackgroundResource(R.drawable.customshape);

Или через XML просто добавьте в контейнер следующий атрибут (например: LinearLayout или любые поля):

android:background="@drawable/customshape"

Ответ 6

Вместо того, чтобы пытаться вырезать углы с вашего макета, почему бы не разместить Drawable поверх него как своего рода фрейм, который соответствует цвету вашего фона?

Ответ 7

[EDIT: похоже, что это будет добавлено в L: https://developer.android.com/preview/material/views-shadows.html#clip, что позволяет клипам вид в форме прямоугольный, круглый или круглый прямоугольный рисунок.]

Я просто очень долго пробовал сделать это сам и пришел к этому ответу, который предполагает, что это невозможно, так как класс View основан на Rect класс. Я только что проверил источник и из комментариев, которые выглядят так, как все еще.

Motorola выпустила Moto 360 (Android Wear смотреть с круглым лицом) позже этим летом, поэтому, возможно, будут обновления для фреймворка, которые позволят просматривать с фигурами, отличными от прямоугольников.