Ahmed-Abdelmeged
9/17/2017 - 6:37 PM

Rounded Layout with specific corners rounded

Rounded Layout with specific corners rounded

package com.abdelmeged.ahmed.roundedlayout;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;

import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;

public class MainActivity extends AppCompatActivity {

    ImageView image;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        image = findViewById(R.id.image_view);

        GlideApp.with(this)
                .load(url)
                .into(image);
    }
}

To make a rounded corner layout or image there is plenty of ways and libraries for this even you can use the CardView attributes to create that

So what is the problem :D . what if you want to make the layout rounded in specific corner or all corners expect one for example . actually there are familiar solution for this to make a XML file like this

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#fff" />
    <corners
        android:bottomLeftRadius="0dp"
        android:bottomRightRadius="0dp"
        android:topLeftRadius="12dp"
        android:topRightRadius="12dp" />
</shape>

and make it background to this layout and you are done. this solution will work for the most cases but what if you try to use Glide or Picasso to upload the image in imageView in that layout. the rounded corner is gone because the image override the background so know you have to solutions

1- To make a custom transformation and pass the image to it but this solution if your images are have different sizes the rounded corner won't be equal in each view.

2-You can make a custom view as wrapper around your views and give it the exactly corners you want to round . the only problem with that solutions that your memory will increase a little bit.

So that is the code for the custom view that I created you can customize it in other way depend on your use case. you can specify the corner radius for specific corner in xml and in runtime

1- Declare a styleable in your attrs.xml file and it's name match the view name

2- Decalre the custom view as the code snippet

3- Decalre your xml file

5- but the drawable file also as backgroud also

4- load the images into the view

This the result of snippet code

I hope that will be helpfully :D

package com.abdelmeged.ahmed.roundedlayout;

/**
 * Created by ahmed on 9/17/2017.
 */

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;

/**
 * Custom wrapper view to get round corner round view
 */
public class RoundedView extends FrameLayout {

    /**
     * The corners than can be changed
     */
    private float topLeftCornerRadius;
    private float topRightCornerRadius;
    private float bottomLeftCornerRadius;
    private float bottomRightCornerRadius;

    public RoundedView(@NonNull Context context) {
        super(context);
        init(context, null, 0);
    }

    public RoundedView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

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

    private void init(Context context, AttributeSet attrs, int defStyle) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundedView, 0, 0);

        //get the default value form the attrs
        topLeftCornerRadius = typedArray.getDimension(R.styleable.
                RoundedView_topLeftCornerRadius, 0);
        topRightCornerRadius = typedArray.getDimension(R.styleable.
                RoundedView_topRightCornerRadius, 0);
        bottomLeftCornerRadius = typedArray.getDimension(R.styleable.
                RoundedView_bottomLeftCornerRadius, 0);
        bottomRightCornerRadius = typedArray.getDimension(R.styleable.
                RoundedView_bottomRightCornerRadius, 0);

        typedArray.recycle();
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        int count = canvas.save();

        final Path path = new Path();

        float[] cornerDimensions = {
                topLeftCornerRadius, topLeftCornerRadius,
                topRightCornerRadius, topRightCornerRadius,
                bottomRightCornerRadius, bottomRightCornerRadius,
                bottomLeftCornerRadius, bottomLeftCornerRadius};

        path.addRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight())
                , cornerDimensions, Path.Direction.CW);

        canvas.clipPath(path, Region.Op.REPLACE);
        canvas.clipPath(path);

        super.dispatchDraw(canvas);
        canvas.restoreToCount(count);
    }

    public void setTopLeftCornerRadius(float topLeftCornerRadius) {
        this.topLeftCornerRadius = topLeftCornerRadius;
        invalidate();
    }

    public void setTopRightCornerRadius(float topRightCornerRadius) {
        this.topRightCornerRadius = topRightCornerRadius;
        invalidate();
    }

    public void setBottomLeftCornerRadius(float bottomLeftCornerRadius) {
        this.bottomLeftCornerRadius = bottomLeftCornerRadius;
        invalidate();
    }

    public void setBottomRightCornerRadius(float bottomRightCornerRadius) {
        this.bottomRightCornerRadius = bottomRightCornerRadius;
        invalidate();
    }
}
<com.abdelmeged.ahmed.roundedlayout.RoundedView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:topLeftCornerRadius="12dp"
    app:topRightCornerRadius="12dp"
    android:background="@drawable/up"
    tools:context="com.abdelmeged.ahmed.roundedlayout.MainActivity">

    <ImageView
        android:layout_width="match_parent"
        android:id="@+id/image_view"
        android:layout_gravity="center"
        android:scaleType="centerCrop"
        android:layout_height="wrap_content" />

</com.abdelmeged.ahmed.roundedlayout.RoundedView>
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RoundedView">
        <attr name="topLeftCornerRadius" format="dimension" />
        <attr name="topRightCornerRadius" format="dimension" />
        <attr name="bottomLeftCornerRadius" format="dimension" />
        <attr name="bottomRightCornerRadius" format="dimension" />
    </declare-styleable>
</resources>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#59dfff" />
    <corners
        android:bottomLeftRadius="0dp"
        android:bottomRightRadius="0dp"
        android:topLeftRadius="12dp"
        android:topRightRadius="12dp" />
</shape>