-1

I want to put two vertical lines in a rounded layout (linear or relative)

Like this picture:

layout with rounded corners, contains two vertical lines

EDIT:

My try:

<RelativeLayout
    android:background="@drawable/rounded_bg"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <View
        android:layout_width="5dp"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"
        android:background="@color/colorPrimaryDark" />


</RelativeLayout>

And Result:

vertical line extending outside background with rounded corners

Bö macht Blau
  • 12,820
  • 5
  • 40
  • 61
Zardchoobe
  • 57
  • 1
  • 7

2 Answers2

0

If you need a transparent area outside of the rounded-corners background, masking the excess parts of the vertical lines is not an option. In this case, you can use a custom View which will work for API levels 17+:

public class RoundedCornersLinearLayout extends LinearLayout{

        private Paint backgroundPaint;
        private Paint linePaint;

        private float cornerRadius;
        private float line_width;
        private float line_margin;
        private RectF rect = new RectF(0, 0, 0,0);

        private Path rectPath = new Path();
        private Path linePath = new Path();

        public RoundedCornersLinearLayout(Context context) {
            super(context);
            init();
        }

        public RoundedCornersLinearLayout(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }

        public RoundedCornersLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }

        private void init() {
            setWillNotDraw(false);

            // add this so Canvas.clipPath() will give the desired result also for devices running Api level 17,
            // see https://stackoverflow.com/a/30354461/5015207
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
                setLayerType(LAYER_TYPE_SOFTWARE, null);
            }
            backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            backgroundPaint.setColor(Color.GREEN);
            backgroundPaint.setStyle(Paint.Style.FILL);
            linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            linePaint.setColor(Color.BLUE);
            linePaint.setStyle(Paint.Style.FILL);

            // with  <dimen name="corner_radius">60dp</dimen> in res/values/dimens.xml
            cornerRadius = getResources().getDimensionPixelSize(R.dimen.corner_radius);
            //  <dimen name="line_width">5dp</dimen>
            line_width =  getResources().getDimensionPixelSize(R.dimen.line_width);
            //  <dimen name="margin_10dp">10dp</dimen>
            line_margin = getResources().getDimensionPixelSize(R.dimen.margin_10dp);
        }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        float measuredWidth = right - left;
        float measuredHeight = bottom - top;
        rect.set(0, 0, measuredWidth, measuredHeight);

        rectPath.reset();
        linePath.reset();

        rectPath.addRoundRect(rect, cornerRadius, cornerRadius, Path.Direction.CW);
        linePath.addRect(measuredWidth - (line_margin + line_width), 0, measuredWidth - line_margin, measuredHeight, Path.Direction.CW);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRoundRect(rect, cornerRadius, cornerRadius, backgroundPaint);    
        canvas.clipPath(rectPath);
        canvas.drawPath(linePath, linePaint);
    }
}

Screenshots for Lollipop (emulator)...

enter image description here

... and Jellybean 4.2.2 (device):

enter image description here

Bö macht Blau
  • 12,820
  • 5
  • 40
  • 61
  • CardView Clipping don't work on android 4.3 . only 5 and above it's ok. I want only Linear or Relative layout. I say in question. – Zardchoobe Jan 03 '19 at 14:40
  • @Zardchoobe - took me some time, but I thought this should be possible even on older devices - the new approach uses a custom View and works on Android 4.2.2 – Bö macht Blau Jan 03 '19 at 17:54
0

Clipping is an expensive operation, and is only truly supported on Lollipop and higher.

If you're okay with Lollipop+ only, and really want to use a RelativeLayout, you can call myView.setClipToOutline(true). If your myView has a rounded background, this will tell the system to clip all children to that rounded shape.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    myView.setClipToOutline(true);
}

If you need rounded corner clipping on pre-Lollipop versions, then the best thing to do is use an overlay to mask parts of the view you don't want to see. That is, create a drawable with opaque corners and a transparent center, and apply that on top of the views you want to clip. This won't actually clip your views, but it will provide the illusion of doing so.

More on this strategy here: https://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

Ben P.
  • 52,661
  • 6
  • 95
  • 123