React-native-pager-view: initialPage does not work on Android with Hermes

Created on 19 Mar 2021  路  8Comments  路  Source: callstack/react-native-pager-view

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: https://github.com/react-navigation/react-navigation/issues/9435#issuecomment-802644853

bug android other-lib

Most helpful comment

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

All 8 comments

same issue

same issue

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);
+        })
       }
     }
   }

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

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

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.

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();
   };

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iqbalfaisal picture iqbalfaisal  路  3Comments

nnajiabraham picture nnajiabraham  路  6Comments

stefan-girlich picture stefan-girlich  路  9Comments

ivan3177 picture ivan3177  路  6Comments

olhapi picture olhapi  路  4Comments