react-navigation-shared-element icon indicating copy to clipboard operation
react-navigation-shared-element copied to clipboard

[v5] android - Source image disappears when going back

Open xseignard opened this issue 4 years ago • 11 comments

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

xseignard avatar May 15 '20 07:05 xseignard

Any idea?

xseignard avatar Jun 04 '20 06:06 xseignard

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!!

edtjulien avatar Jun 06 '20 18:06 edtjulien

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

julianfrancodev avatar Jun 07 '20 03:06 julianfrancodev

Same here, but when using the Android Back Button it works. But not for navigation.goBack();

kundarmah avatar Jun 14 '20 08:06 kundarmah

Here is my workaround:

  1. Make a substitute exact same image with position 'absolute' to cover the shared element.
  2. Use following snippet to hide the substitution during the transition:
  const [visible, setVisible] = useState(true);

  useFocusEffect(
    useCallback(() => {
      requestAnimationFrame(() => {
        setVisible(true);
      });

      return () => {
        setVisible(false);
      };
    }, []),
  );
  1. use conditional render to show the substitution when the screen is focused:
 {visible && (
            <Image
              source={sharedImage.source}
              style={styles.logoSubstitution}
              resizeMode="contain"
            />
          )}

jp928 avatar Jun 14 '20 21:06 jp928

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.

nathell avatar Jul 23 '20 19:07 nathell

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).

nathell avatar Jul 24 '20 09:07 nathell

Any workaround? Have the same issue if i go back programmatically. It works with the hardware button

kanelloc avatar Sep 28 '20 21:09 kanelloc

I suppose this has something to do with the Image not being cached. Have you tried using "FastImage"?

iduuck avatar Nov 07 '20 20:11 iduuck

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.

alexanderkrust avatar Apr 21 '21 11:04 alexanderkrust

which helped me too, putting gestureEnabled: false in options on your screen

lucasvieceli avatar Aug 10 '21 17:08 lucasvieceli