Dimezis/BlurView

How to get a round corner BlurView?

ScuAdam opened this issue · 18 comments

How to get a round corner BlurView?

Create a rounded drawable, as usual, set it as a background.
And do
blurView.setOutlineProvider(ViewOutlineProvider.BACKGROUND);
blurView.setClipToOutline(true);

It works, Thanks for your help :) 👍 @Dimezis

This crashes my app:
java.lang.NoClassDefFoundError: android.view.ViewOutlineProvider
at com.estudiotrilha.inevent.fragment.PrinterModeSelectorFragment.onViewCreated(PrinterModeSelectorFragment.java:120)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1430)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1750)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1819)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2590)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2377)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2332)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2239)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3231)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3181)

@mauriciogior because it's API 21, and you are running it <21. Android Studio should give you a warning

@Dimezis so for API < 21, no round corners?

For sure it's possible to have rounded corners, but you'll have to fork the lib and implement it manually.
You can draw blurred bitmap with a mask, or draw a transparent rounded corners on top of it. Pretty simple

Here is a solution for anyone wondering how to do it (just wrap BlurView inside CornerView):

public class CornerView extends FrameLayout {
    private Path path = new Path();
    private float radius = 0;

    public CornerView(Context context) {
        super(context);
    }

    public CornerView(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CornerView);

        try {
            radius = a.getDimension(R.styleable.CornerView_radius, 0);

        } finally {
            a.recycle();
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        RectF rect = new RectF();

        path.reset();
        rect.set(0, 0, w, h);
        path.addRoundRect(rect, radius, radius, Path.Direction.CW);
        path.close();
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        int save = canvas.save();
        canvas.clipPath(path);
        super.dispatchDraw(canvas);
        canvas.restoreToCount(save);
    }

}

I can't get this to work, can anyone see what I am doing wrong? I have a semi transparent drawable with rounded corners, which is used as the background to the BlurView (api is 28).

image

Fragment's onCreateView

`       float radius = 16f;

        View decorView = getActivity().getWindow().getDecorView();
        ViewGroup rootView = (ViewGroup) decorView.findViewById(android.R.id.content);
        Drawable windowBackground = decorView.getBackground();
        BlurView blurView = v.findViewById(R.id.home_text_view_balance_blur);

        blurView.setupWith(rootView)
                //.setFrameClearDrawable(windowBackground)
                .setBlurAlgorithm(new RenderScriptBlur(getActivity()))
                .setBlurRadius(radius);
                //.setHasFixedTransformationMatrix(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            blurView.setOutlineProvider(ViewOutlineProvider.BACKGROUND);
            blurView.setClipToOutline(true);
        }`

@danielwilson1702 post your drawable

My blind guess you're using per-corner radius, which is not supported.

<corners android:bottomLeftRadius="..."
        android:bottomRightRadius="..."
        android:topLeftRadius="..."
        android:topRightRadius="..."/>

And you should use just

 <corners android:radius="..." />

Brilliant thank you, I wouldn't have thought of that 💯

Hi Dimezis,

Can you please tell me where I am getting wrong

` <eightbitlab.com.blurview.BlurView
android:id="@+id/topBlurView"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="0dp"
android:outlineProvider="paddedBounds"
app:blurOverlayColor="@android:color/transparent"
tools:targetApi="lollipop">

        <com.travelist.hi5.custom.CenteredToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:elevation="0dp"
            android:paddingEnd="@dimen/margin_7dp"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll" />
    </eightbitlab.com.blurview.BlurView>`

Also I am Using in MainActivity.Class

` topBlurView = findViewById(R.id.topBlurView);

    topBlurView.setOutlineProvider(ViewOutlineProvider.BACKGROUND);
    topBlurView.setClipToOutline(true);`

Here is a solution for anyone wondering how to do it (just wrap BlurView inside CornerView):

public class CornerView extends FrameLayout {
    private Path path = new Path();
    private float radius = 0;

    public CornerView(Context context) {
        super(context);
    }

    public CornerView(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CornerView);

        try {
            radius = a.getDimension(R.styleable.CornerView_radius, 0);

        } finally {
            a.recycle();
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        RectF rect = new RectF();

        path.reset();
        rect.set(0, 0, w, h);
        path.addRoundRect(rect, radius, radius, Path.Direction.CW);
        path.close();
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        int save = canvas.save();
        canvas.clipPath(path);
        super.dispatchDraw(canvas);
        canvas.restoreToCount(save);
    }

}

Can you please send the attr class also

@Dimezis Is it possible to have only some of the corners rounded? For example, only top left and top right?

P.S. Дякую за лібу!

Overall it's possible if you subclass the BlurView and mask those corners manually.

But it's not possible with the XML drawable and clipToOutline, because it doesn't support complex shapes.

Overall it's possible if you subclass the BlurView and mask those corners manually.

But it's not possible with the XML drawable and clipToOutline, because it doesn't support complex shapes.

@Dimezis is there any example to achieve this? I am really weak with canvas and paint API.

@nauhalf there's a solution in this thread already - CornerView.
Just change the path the way you want