Dimezis / BlurView

Dynamic iOS-like blur of underlying Views for Android
Apache License 2.0
3.48k stars 331 forks source link

BlurView does not honour changes to scaleX/scaleY #183

Open ptsekov opened 2 years ago

ptsekov commented 2 years ago

Please include: 1) Library version: 2.0.2 2) Device and OS version: any 3) Detailed steps to reproduce the issue:

  1. Build and run the modified sample app from https://github.com/ptsekov/BlurView/tree/issue/scaleXY
  2. Select the RECYCLERVIEW page
  3. Click on any card to scale it. Examine the blurred area of the card and notice that it did not update - it is clearly visible when looking at the bottom of the card.

    I was able to make it work as expected by invoking setupWith() after setting scaleX/scaleY. Look at the modified ExampleListAdapter and uncomment the commented line in the card onClick() listener to see it work as expected.

https://user-images.githubusercontent.com/8249935/187984892-a02f74e5-9cb0-4419-9326-6aa07b8926f9.mp4

ptsekov commented 2 years ago

It seems PreDrawBlurController does not properly detect the changes to scaleX/scaleY and does not update its internal state. Calling setupWith() creates the controller and its state however it seem to be fairly heavy. Is there a way to update controller state without recreating it from scratch. It seem like BlurView.onSizeChanged() does exactly that.

Dimezis commented 2 years ago

Weird stuff. Can't really answer why it's happening off the top of my head.

Calling setupWith() creates the controller and its state however it seem to be fairly heavy.

Yes, it recreates the bitmap among other stuff, so it's better to avoid it

It seem like BlurView.onSizeChanged() does exactly that

Essentially it's almost as heavy as the setupWith call, because it recreates the bitmap with the new size. Also, scaleX/Y doesn't really change the size reported by the View, so it shouldn't even matter. The bitmap size stays the same.

So I'm not even sure which part of setupWith fixes this issue. Also scaling is not really something that has to be explicitly supported by custom Views during drawing on Canvas, so that's also weird. Will try to debug it

ptsekov commented 2 years ago

Funny thing is it seems to break only in the vertical direction, on the horizontal direction all seems fine. In any case let me know if I can help in any way to track this down.

Dimezis commented 2 years ago

So in case you need a quick fix, you can fork the library and change 1 in this line to the scale factor you're using.

The problem is that I can't take the scaleX/Y from the blurView or rootView, because when you set the scale of their parent, it's not reflected in the properties of the child View, so their scale still returns 1. So you need to pass there the actual scale somehow.

I'm not yet sure it's the cleanest or the most correct fix, and it still doesn't explain why setupWith works, but that's at least something.

ptsekov commented 2 years ago

@Dimezis, I have modified setupInternalCanvasMatrix() as per your suggestion. To get the proper scaleX/scaleY value I've modified the sample to call setupWith() with the view that has scaleX/scaleY applied i.e. the CardView. You can pull the changes from my branch and see the result.

The sample seems to work as expected now the only problem being that the BlurView captures the click animation which is to be expected I guess - in my real app this should not be a problem though since the image covers the whole ImageView area.