react-native-blur: Bur is invalid when first time load on android
Bur is invalid when first time load on android
When replacing the picture of the mask below sometimes does not update the content on android
react-native-blur@master and react-native-blur@3.0.0-alpha 2 versions have above the problem
// my code:
`
imageLoaded() { this.setState({viewRef: findNodeHandle(this.refs.backgroundImage) }); // setTimeout(() => { // this.setState({viewRef:findNodeHandle(this.refs.backgroundImage) }); // }, 200); }
renderBlurView() {
return (
<View >
{this.state.viewRef && <BlurView
viewRef={this.state.viewRef}
style={styles.blurView}
blurRadius={6}
blurType={'dark'}
blurAmount = {12}
/>}
</View>
)
`
`
//render 函数 : <Image source={this.state.customImage} style={[styles.backImage,styles.blurView]} ref={‘backgroundImage’} onLoadEnd={this.imageLoaded.bind(this)} /> {this.renderBlurView()} <View style={styles.contentContainer}> <TouchableOpacity onPress={this.headerOnClicked.bind(this)}> <Image style={styles.circleImage} source={this.state.customImage} onError = {this.imageHeadOnloadEndError.bind(this)} > </Image> //…
`
About this issue
- Original URL
- State: open
- Created 7 years ago
- Comments: 16 (4 by maintainers)
tl;dr BlurView basically takes screenshot of target view and blurs it (all libs do this). But when onLoadEnd from Image is called, the image is not rendered yet, just loaded, therefor the screenshot is empty => no blur 😢. Best option right now is to setTimeout and optionally fade in image.
So I’ve been trying to figure this out as well. Seems like Fresco is loading the image and setting the asynchronously, thus https://github.com/facebook/react-native/blob/3fda6a9a2b380a750b72d369f5fb4f11540ad1ef/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java#L214 is beeing called and will emit
onLoadEndbefore view is invalidated and redrawn.To clarify how I understand blurview works. As soon as we set
viewRefinsetStateit will:android.renderscript.ScriptIntrinsicBlur(all libs I found basically to the same, mostly they differ a bit in memory management, some even have a slower java based fallback for older devices: e.g. https://github.com/Manabu-GT/EtsyBlur, https://github.com/mmin18/RealtimeBlurView, https://github.com/gogopop/BlurKit-Android, https://github.com/Dimezis/BlurView, https://github.com/wasabeef/Blurry)If we use the
onLoadEndthe Image is not rendered yet into the target view, thus only giving back a blurred grey image. If we use setTimeout it will mostly work, but will kind of flash the original image unblurred at first.Solution I see three options here:
<BlurImageView src=.../>blurRadiusto Images, just wait for it to land, but would not be backwards compatible…Mentions There is a fork that uses Blurry, but it should not make a difference: https://github.com/carlesnunez/react-native-blurry
ScrollView-Support Basically we would need to recreate snapshot and blur on every scrollEvent. For large scroll-components we would need to screenshot only the visible bits. There is already a fork for the underlying lib Android uses, that would kind of work with ScrollView but it is not yet merged and tested, so probably we won’t see this any time soon: https://github.com/500px/500px-android-blur/pull/10/files
Correct on both counts Kumar. My message wasn’t meant to imply otherwise.
Many people in this thread just need a solution that works for Image.
Wow, it seems that whenever I write up a post or a comment, I always find the answer immediately afterwards. I think I just figured it out: http://stackoverflow.com/a/7735122/304706
We just need to add a global layout listener to the referenced view, and update the blur whenever it changes. This fixes the race condition, but it always mean that we now have a real-time blur whenever the view changes.
I’m going to try this out and see if I can get it to work.
Hi @roselind, sorry about this, it’s a very tricky race condition that I’ve also been struggling with. I think the best workaround is to just add a small timeout, like you did in your example:
I need to figure out the right way to do this. I think there might be a bug in the blurring library that we are using, or perhaps the Android view has not finished rendering before we try to blur it. Any help would be appreciated, if you have time to look at the source code of react-native-blur and could help me figure this out.