Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initialPage does not work on Android with Hermes #312

Closed
troZee opened this issue Mar 19, 2021 · 9 comments · Fixed by #322
Closed

initialPage does not work on Android with Hermes #312

troZee opened this issue Mar 19, 2021 · 9 comments · Fixed by #322
Labels
android bug Something isn't working other-lib

Comments

@troZee
Copy link
Member

troZee commented Mar 19, 2021

Current Behavior

initialRouteName don't work. Or scrolling to first route. Problem only on Android with Hermes (no problem on iOS with Hermes).

Expected Behavior

Tabs should open specified initialRouteName on init.

How to reproduce

https://github.com/Bardiamist/initialRouteRame

Your Environment

software version
iOS or Android Android (Checked on Android 11 simulator)
@react-navigation/native 5.9.3
@react-navigation/material-top-tabs 5.3.14
react-native-tab-view 3.0.0
react-native 0.64.0
expo -
node 15.12.0
npm or yarn yarn 1.22.10

Original post: react-navigation/react-navigation#9435 (comment)

@troZee troZee added other-lib android bug Something isn't working labels Mar 19, 2021
@utae
Copy link

utae commented Mar 19, 2021

same issue

1 similar comment
@Ashalbulk
Copy link

same issue

@KusStar
Copy link

KusStar commented Mar 26, 2021

This works for me:
https://github.com/callstack/react-native-pager-view/blob/master/src/PagerView.tsx#L64

@@ -61,7 +61,9 @@ export class ViewPager extends React.Component<ViewPagerProps> {
     // On iOS we do it directly on the native side
     if (Platform.OS === 'android') {
       if (this.props.initialPage != null) {
-        this.setPageWithoutAnimation(this.props.initialPage);
+        requestAnimationFrame(() => {
+          this.setPageWithoutAnimation(this.props.initialPage);
+        })
       }
     }
   }

@tdekoning
Copy link

I was encountering the same behavior, the fix suggested by @KusStar seems to work

Lukas-Heiligenbrunner added a commit to Lukas-Heiligenbrunner/react-native-pager-view that referenced this issue Apr 6, 2021
troZee added a commit that referenced this issue Apr 8, 2021
* fix #312 - no initial page load on Android

* Update PagerView.tsx

Co-authored-by: troZee <12766071+troZee@users.noreply.github.com>
@danilobuerger
Copy link
Contributor

The proposed fix leads to another issue. Now the first page is visible before it skips to the initialPage.

@danilobuerger
Copy link
Contributor

I don't think this change comes from using Hermes. I can reproduce it with JSC too. It seems like when upgrading to 0.64 (from 0.63.4) the order of calling addView and receiveCommand in PagerViewViewManager is changed.

@danilobuerger
Copy link
Contributor

Since I cant upgrade to rn-pager-view v5 at the moment (facebook/react-native#31245 happens with rn64 & pager-view v5, but not v4), I have patched v4 to fix the problem without a flash of the first page. Maybe someone wants to port this to v5:

diff --git a/node_modules/react-native-pager-view/android/src/main/java/com/reactnativecommunity/viewpager/ReactViewPager.java b/node_modules/react-native-pager-view/android/src/main/java/com/reactnativecommunity/viewpager/ReactViewPager.java
index d2ca9b0..d4f5bd1 100644
--- a/node_modules/react-native-pager-view/android/src/main/java/com/reactnativecommunity/viewpager/ReactViewPager.java
+++ b/node_modules/react-native-pager-view/android/src/main/java/com/reactnativecommunity/viewpager/ReactViewPager.java
@@ -144,6 +144,8 @@ public class ReactViewPager extends VerticalViewPager {
   private final EventDispatcher mEventDispatcher;
   private boolean mIsCurrentItemFromJs;
   private boolean mScrollEnabled = true;
+  private int mInitialPage = 0; 
+  private boolean mInitialPageWasSet = false;
 
   public ReactViewPager(ReactContext reactContext) {
     super(reactContext);
@@ -212,6 +214,12 @@ public class ReactViewPager extends VerticalViewPager {
   @Override
   protected void onAttachedToWindow() {
     super.onAttachedToWindow();
+
+    if (!mInitialPageWasSet) {
+      setCurrentItemFromJs(mInitialPage, false);
+      mInitialPageWasSet = true;
+    }
+
     // The viewpager reset an internal flag on this method so we need to run another layout pass
     // after attaching to window.
     this.requestLayout();
@@ -228,6 +236,10 @@ public class ReactViewPager extends VerticalViewPager {
     }
   };
 
+  /*package*/ void setInitialPage(int initialPage) {
+    mInitialPage = initialPage;
+  }
+
   /*package*/ void addViewToAdapter(View child, int index) {
     getAdapter().addView(child, index);
   }
diff --git a/node_modules/react-native-pager-view/android/src/main/java/com/reactnativecommunity/viewpager/ReactViewPagerManager.java b/node_modules/react-native-pager-view/android/src/main/java/com/reactnativecommunity/viewpager/ReactViewPagerManager.java
index f8a4cb7..7a98e14 100644
--- a/node_modules/react-native-pager-view/android/src/main/java/com/reactnativecommunity/viewpager/ReactViewPagerManager.java
+++ b/node_modules/react-native-pager-view/android/src/main/java/com/reactnativecommunity/viewpager/ReactViewPagerManager.java
@@ -146,4 +146,9 @@ public class ReactViewPagerManager extends ViewGroupManager<ReactViewPager> {
         pager.setOffscreenPageLimit(offscreenPageLimit);
     }
 
+    @ReactProp(name = "initialPage")
+    public void setInitialPage(ReactViewPager pager, int initialPage) {
+        pager.setInitialPage(initialPage);
+    }
+
 }
diff --git a/node_modules/react-native-pager-view/src/ViewPager.tsx b/node_modules/react-native-pager-view/src/ViewPager.tsx
index 5a413b3..a118a66 100644
--- a/node_modules/react-native-pager-view/src/ViewPager.tsx
+++ b/node_modules/react-native-pager-view/src/ViewPager.tsx
@@ -57,15 +57,6 @@ export class ViewPager extends React.Component<ViewPagerProps> {
   private isScrolling = false;
   private viewPager = React.createRef<typeof ViewpagerViewManager>();
 
-  componentDidMount() {
-    // On iOS we do it directly on the native side
-    if (Platform.OS === 'android') {
-      if (this.props.initialPage != null) {
-        this.setPageWithoutAnimation(this.props.initialPage);
-      }
-    }
-  }
-
   public getInnerViewNode = (): ReactElement => {
     return this.viewPager.current!.getInnerViewNode();
   };

@smacgregor
Copy link

Thank you @danilobuerger - I patch-packaged your change and it fixed this issue for me. - initial page was not appearing on launch after upgrading to react-native 0.64.

@TfADrama
Copy link

@danilobuerger

Thank you!
I had the same issue, but i couldn't upgrade to version 5 because i'm using pager-view with webviews and in Android the vertical scroll from the webview conflicts with the scroll from the pager view.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android bug Something isn't working other-lib
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants