react-navigation-shared-element
react-navigation-shared-element copied to clipboard
[v5] android - Source image disappears when going back
Hello, First of all thanks for this nice lib 👍 I'm using it with the following versions:
"@react-navigation/native": "^5.3.2",
"@react-navigation/stack": "^5.3.5",
"react-navigation-shared-element": "^5.0.0-alpha1",
"react-native-shared-element": "^0.7.0",
It's working well, but I have a small weird bug happening on android. When I press an Icon on top of a shared element to go back, the source element doesn't shows up.
If I press the OS back button, or any element doing a navigation.goBack
provided this element is not on top of the SharedElement
, it's working ok.
Here is a screen record: https://imgur.com/a/mUn8HfU
As you can see, when I click on the red bordered arrow on top the source image of the transition doesn't show up. If I click on the "link" (Voir sur la carte) below the image, the source image shows up. (both Arrow and "link" triggers a navigation.goBack
)
Any idea?
PS: my react-native info
:
info Fetching system and libraries information...
System:
OS: macOS Mojave 10.14.6
CPU: (8) x64 Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
Memory: 3.90 GB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 12.14.1 - ~/.nvm/versions/node/v12.14.1/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.13.4 - ~/.nvm/versions/node/v12.14.1/bin/npm
Watchman: Not Found
Managers:
CocoaPods: 1.9.1 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
Android SDK: Not Found
IDEs:
Android Studio: 3.6 AI-192.7142.36.36.6241897
Xcode: 11.2.1/11B500 - /usr/bin/xcodebuild
Languages:
Java: 1.8.0_242 - /usr/bin/javac
Python: 2.7.10 - /usr/bin/python
npmPackages:
@react-native-community/cli: Not Found
react: 16.13.1 => 16.13.1
react-native: 0.62.2 => 0.62.2
npmGlobalPackages:
*react-native*: Not Found
Any idea?
Hey, I have exactly the same issue.
In the same case of xseignard (carousel view above a map) and on a classic column FlatList of start screen.
No problem on iOS, no problem by using the hardware backbutton of Android. But the issue happen when I put a clickable Icon on the SharedElement. If I move the clickable Icon in other place. That's work well.
To be more precise in my case about the Icon button positioning: top:100 and less, I have the issue. top:100 and more, no issue (even if the Icon button is still on top of the Shared Element after 100). The weird thing, is when I put the button at top:110,
- If I press the button on his top border: issue
- If I press the button on his bottom border: no issue
I tried many tricks, even using native-gesture-handler to have a native press event, or I did custom transitions. Still the same issue. My only way is finally to unactivate back animation for Android.
Would be amazing to have some help too. Shared Element is so smooth and wonderful looking! I would love to use it in my project.
Thank you so much for your amazing work anyway!!
Same iusse on android.
using the following versions:
Library | Version |
---|---|
react-native | 0.62.2 |
react-navigation-shared-element@next | ^5.0.0-alpha1 |
react-native-shared-element | ^0.7.0 |
I'm seeing that in API Level 29 and API level 28
Same here, but when using the Android Back Button it works. But not for navigation.goBack();
Here is my workaround:
- Make a substitute exact same image with position 'absolute' to cover the shared element.
- Use following snippet to hide the substitution during the transition:
const [visible, setVisible] = useState(true);
useFocusEffect(
useCallback(() => {
requestAnimationFrame(() => {
setVisible(true);
});
return () => {
setVisible(false);
};
}, []),
);
- use conditional render to show the substitution when the screen is focused:
{visible && (
<Image
source={sharedImage.source}
style={styles.logoSubstitution}
resizeMode="contain"
/>
)}
I can confirm this happening in my app as well. Same dependency versions as in this comment.
Here are my extra observations:
- I can confirm that using the hardware back button completely sidesteps the issue. It only happens when navigating back programmatically (e.g., from screen header).
- It doesn't happen always. Whether or not it does is somewhat predictable in my case, but not 100%. In my app, I have one screen with a lot of images wrapped in RecyclerListView and another that shows a zoomed version of a single image, with a shared-element transition between them. Zooming most of the images trigger the bug, but for one of them it never happens. Both the image dimensions and position seem to matter, as the same one placed elsewhere does trigger the bug.
- What does always happen for me, 100% of the time, is that navigating back programmatically (but not w/ hardware back button) doesn't trigger the zoom animation. I believe this has been reported as #91. I have a hunch that the two issues are related.
I have also tried a minimal, proof-of-concept app, with two screens and one image only. I found that it exhibits the no-animation-on-going-back bug, but not the source-image-disappearing-on-going-back bug.
See also my related comment there.
I've actually just checked and the issue is no longer reproducible on 3.0.0 (which seems to be newer than 5.0.0-alpha1).
Any workaround? Have the same issue if i go back programmatically. It works with the hardware button
I suppose this has something to do with the Image
not being cached. Have you tried using "FastImage"?
What helped me kinda fixing my shared-elements on android is posted here #130. For android i use the enableScreens function.
import {enableScreens} from 'react-native-screens';
if (Platform.OS === 'ios') {
enableScreens(false);
} else {
enableScreens(true);
}
Also it was very important to add mode="modal"
on the navigator. Here is an example:
<SearchTabStack.Navigator
mode="modal"
screenOptions={{
gestureEnabled: false,
...TransitionPresets.ModalSlideFromBottomIOS,
transitionSpec: {
open: {
animation: 'timing',
config: {
duration: 250,
},
},
close: {
animation: 'timing',
config: {
duration: 250,
},
},
},
cardOverlayEnabled: true,
cardStyleInterpolator: ({current: {progress}}) => ({
cardStyle: {
opacity: progress,
},
}),
}}>
Unfortunately the transition works only with the native android back button. I really hope it helps you.
which helped me too, putting gestureEnabled: false in options on your screen