react-native-blur icon indicating copy to clipboard operation
react-native-blur copied to clipboard

[Android] Blur not working

Open ABleas opened this issue 7 years ago • 25 comments

I have been trying to get the blur effect to work on Android for a long time now, after finally getting rid of compile and ViewGroup issues, the blur view will not blur anything.

It worked right off the bat in iOS, and continues to work. I am blurring a Google map view under a popup window of sorts. Here's an excerpt:

        <View key={id} style={styles.placeItem}>
          <BlurView blurType="light" blurAmount={5} style={styles.placeItemBlur}/>
          <ScrollView contentContainerStyle={styles.placeItemContainer}>
            <Text style={styles.placeTitleText}>{placeProps.name}</Text>
            [...]
          </ScrollView>
        </View> 

This view is itself a child of the map view, which is a child of a scrollable tab view. As others have suggested, I tried setting backgroundColor: 'transparent' on the 'thing I want to blur' (the map, and various other views), with no effect.

Am I missing something obvious? Thanks!

ABleas avatar Mar 16 '17 10:03 ABleas

There are other issues about this no longer working on Android with latest react native version. #156 talks about it in greater detail.

Also note that the Android usage is much different than iOS. This may change once the fix for Android is made.

anshul-kai avatar Mar 16 '17 18:03 anshul-kai

The obvious thing you're missing is that you're using the iOS props, however Android uses different ones.

iOS

      blurType="light"
      blurAmount={5}

Android

          blurRadius={15}
          downsampleFactor={5}
          overlayColor={'rgba(255, 255, 255, .25)'}
          viewRef={this.state.viewRef}

I'm having trouble doing this with anything besides blurring an Image however.

booboothefool avatar Mar 16 '17 19:03 booboothefool

Thanks guys, thats really helpful. I was working off the readme, which doesn't include Android usage, nor does it specify being a purely iOS demonstration... I guess I should refer to examples instead.

So are we to understand that you can only blur a single view on Android, and not everything above the blur view, as with iOS? That's kind of a bummer.

I still can't get my map view to blur, even after adding the appropriate props and a viewRef. So I don't know if this is a limitation of the Android lib or I should try something else? Here is my updated (cross platform) call:

<BlurView
  blurType="light"
  blurAmount={5}
  blurRadius={15}
  downsampleFactor={5}
  overlayColor={'rgba(255, 255, 255, .25)'}
  viewRef={this.state.blurViewRef}
  style={styles.placeItemBlur}/>

and somewhere outside the render() stack, setting state:

blurViewRef: findNodeHandle(this.mapView),

Still no blur 😞

I briefly looked around for Android blur views and there are numerous others besides 500px-android-blur.. maybe one of them would have features more similar to iOS blur? Android Arsenal link

ABleas avatar Mar 17 '17 05:03 ABleas

No problem. I found that documentation for most packages is pretty solid with this library being an exception. I only included this library recently so can't speak to how it used to work. I'm hoping that using absolute positioning should make it work about the same on both platforms once we have a fix for Android.

As you may have already noticed, the authors are still looking for someone to fix this on Android. Not ideal, but you can use my hack below if you'd like.

import RNBlur from 'react-native-blur';

const BlurView = ({children, ...rest}) => Platform.select({
    ios: <RNBlur.BlurView {...rest}>{children}</RNBlur.BlurView>,
    android: <View style={[rest.style, {backgroundColor: 'rgba(16,16,16,0.9)'}]}>{children}</View>
  })

anshul-kai avatar Mar 17 '17 06:03 anshul-kai

Thanks @a-koka. I am trying to keep Platform specific code out of my implementation as much as possible, but that's a nice fix-up.

I would offer to try and patch it up myself, but right now I can't devote that much attention to this. Since this module is the closest to cross platform blur at the moment, hopefully we can sort her out pretty soon!

ABleas avatar Mar 17 '17 06:03 ABleas

Anyone find a fix for Android or recommended a different library for Android? This works for iOS but not Android.

jkbreunig avatar Mar 31 '17 19:03 jkbreunig

Oh man... After spending 2-3 hours getting this to compile and run on Android, and then another hour trying out a whole bunch of different things, I finally found the issue that says it doesn't work at all on Android :/

It would have been really nice if the README could be updated with a big h3 heading at the top, saying that this only works on iOS.

ndbroadbent avatar Apr 10 '17 13:04 ndbroadbent

I've pushed a fix for Android: #173

You can try it out now by adding this to your package.json:

"react-native-blur": "ndbroadbent/react-native-blur#android-fix",

Then make sure you update your Gradle version (at least 1.5.0, but you may as well use 2.2.3), and then add those "renderscript" lines. I've added these instructions to the README.

ndbroadbent avatar Apr 10 '17 17:04 ndbroadbent

For my case, It seems react-native-maps (AirMap library) is currently incompatible with the underlying (500px) blur lib. I'm seeing this error: BlurringView cannot be cast to android.view.ViewGroup That's with or without your fixes @ndbroadbent. Although I was able to blur an image view.

ABleas avatar Apr 11 '17 08:04 ABleas

Hi @ABleas, this is actually a limitation of the 500px blur library. The BlurView cannot contain any child views, and it cannot be a child of the view that is being blurred (otherwise there is an infinite loop when it tries to blur itself). So you'll need to absolutely position the BlurView behind whatever views you want to show on top.

I'm about to submit a new PR with better error messages, hopefully that will make things clearer when something goes wrong.

ndbroadbent avatar Apr 11 '17 08:04 ndbroadbent

That's odd because if I try to put the BlurView outside of the parent, nothing is blurred. I get the error in this scenario:

<MapView>
  //...
  <BlurView/>
</MapView>
<View key={'popup'}/>

But no error (and no blurring) like this:

<MapView>
  //...
</MapView>
<BlurView/>
<View key={'popup'}/>

Both scenarios produce the desired effect on iOS, though.

ABleas avatar Apr 11 '17 08:04 ABleas

Are you passing the correct viewRef and using the Android-specific props?

See: https://github.com/react-native-community/react-native-blur#android

ndbroadbent avatar Apr 11 '17 08:04 ndbroadbent

My comment above shows how my BlurView is set up. The viewRef seems valid I should say that the error is thrown by the maps library, so it seems to have at least found the blur view to add. I haven't the time to dig into it myself right now.

ABleas avatar Apr 11 '17 08:04 ABleas

@ABleas ah sorry, yes that looks fine. Well, this is the only correct way, to avoid the infinite loop:

<MapView>
  //...
</MapView>
<BlurView />
<View key={'popup'}/>

I'm not sure why the Google Maps view couldn't be blurred. This is just a guess, but maybe they do some fancy OpenGL rendering that skips the normal Android views, so the 500px blur library doesn't work.

I'll try to add Google Maps to the example project and see if I can figure it out.

ndbroadbent avatar Apr 11 '17 10:04 ndbroadbent

Yes I believe Google Maps uses OpenGL ES 2 to render. It's a shame if they're not compatible. GPU acceleration would surely be the fastest way to do a blur effect...

ABleas avatar Apr 11 '17 11:04 ABleas

Ah yes, they are using the GPU to do the blur, via RenderScript. But I think getting the actual source view from Google Maps might be the problem.

Sorry, I don't have any more time to spend on this, but maybe someone else will be able to figure this out.

ndbroadbent avatar Apr 11 '17 15:04 ndbroadbent

Did you have found a solution @ABleas ? Or you just give up this feature ?

zagoa avatar Dec 11 '17 09:12 zagoa

@ABleas Could you show me the piece of code that you set your blurViewRef using findNodeHandle(this.mapView)?

I had a similar problem and I solved it like that:

`class ContainerComponent extends Component {

constructor(props) {
    super(props);
    this.state = { viewRef: 0 } ;
}

componentDidMount() {
    this.setState({ viewRef: findNodeHandle(this.componentToBlur) });
}

render() {
    return (
        <View>
            <Component
                style={styles.absolute}
                ref={(ref) => { this.componentToBlur = ref; }}
            />
            <BlurView
                style={styles.absolute}
                viewRef={this.state.viewRef}
                blurType="light"
                blurAmount={3}
                blurRadius={3}
            />
        </View>
    );
}

}`

PedroHRDiniz avatar Sep 25 '18 18:09 PedroHRDiniz

Hi, I am doing blur view for android. And I am also successful to make the image blur. But I wonder how could I make the image become blurring a part, 50% blur and 50% normal for example. P/S: I did set height for <BlurView /> but it's no luck

hauhuynh1208 avatar Jun 12 '19 05:06 hauhuynh1208

it's because you need a viewRef property on android version of your app. for more info you can read documentation https://github.com/react-native-community/react-native-blur#android

byteab avatar Jul 31 '19 06:07 byteab

This is a duplicate of #187 . Bottomline, some dynamic content like Google Map doesn't work due to Android limitations (as explained here: https://github.com/Kureev/react-native-blur/issues/187#issuecomment-301239382)

chrisregner avatar Jul 02 '21 10:07 chrisregner

stumbled accross this in 2023 now while trying to implement a glassmorphism-style navbar. It's still not working on android. Anyone has any fixes/alternatives by now?

hfllr avatar May 26 '23 11:05 hfllr

@hfllr use expo-image

byteab avatar May 26 '23 20:05 byteab

@hfllr use expo-image

how should this solve the problem with getting google maps to blur?

hfllr avatar May 27 '23 08:05 hfllr

@hfllr oh my bad 🤦‍♂️ sorry it's not going to help you

byteab avatar May 27 '23 17:05 byteab