React-native-navigation: Android app crashes when options.bottomTabs has currentTabIndex and titleDisplayMode set

Created on 17 Jun 2020  路  3Comments  路  Source: wix/react-native-navigation

Issue Description

If I add to options.bottomTabs both currentTabIndex AND titleDisplayMode: "alwaysShow" app crashes on Android (I get _App has stopped working alert_).
If it has only one of defined/added, everything works fine.

Here is stacktrace from Bugsnag:

java.lang.NullPointerException Attempt to invoke virtual method 'void android.widget.ImageView.setSelected(boolean)' on a null object reference 
    AHBottomNavigation.java:720 com.aurelhubert.ahbottomnavigation.AHBottomNavigation.updateItems
    AHBottomNavigation.java:1299 com.aurelhubert.ahbottomnavigation.AHBottomNavigation.setCurrentItem
    BottomTabsController.java:211 com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsController.selectTab
    BottomTabsPresenter.java:129 com.reactnativenavigation.presentation.BottomTabsPresenter.applyBottomTabsOptions
    BottomTabsPresenter.java:51 com.reactnativenavigation.presentation.BottomTabsPresenter.applyOptions
    BottomTabsController.java:93 com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsController.applyOptions
    ViewController.java:241 com.reactnativenavigation.viewcontrollers.ViewController.onViewAppeared
    ChildController.java:50 com.reactnativenavigation.viewcontrollers.ChildController.onViewAppeared
    ViewController.java:294 com.reactnativenavigation.viewcontrollers.ViewController.onGlobalLayout
    ViewTreeObserver.java:945 android.view.ViewTreeObserver.dispatchOnGlobalLayout
    ViewRootImpl.java:2250 android.view.ViewRootImpl.performTraversals
    ViewRootImpl.java:1392 android.view.ViewRootImpl.doTraversal
    ViewRootImpl.java:6752 android.view.ViewRootImpl$TraversalRunnable.run
    Choreographer.java:911 android.view.Choreographer$CallbackRecord.run
    Choreographer.java:723 android.view.Choreographer.doCallbacks
    Choreographer.java:658 android.view.Choreographer.doFrame
    Choreographer.java:897 android.view.Choreographer$FrameDisplayEventReceiver.run
    Handler.java:790 android.os.Handler.handleCallback
    Handler.java:99 android.os.Handler.dispatchMessage
    Looper.java:164 android.os.Looper.loop
    ActivityThread.java:6494 android.app.ActivityThread.main
    Method.java:-2 java.lang.reflect.Method.invoke
    RuntimeInit.java:438 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run
    ZygoteInit.java:807 com.android.internal.os.ZygoteInit.main

Steps to Reproduce / Code Snippets / Screenshots

Here is our setRoot code:

  await Navigation.setRoot({
    root: {
      bottomTabs: {
        id: testID.menu.root,
        children: generateMainMenu(),
        options: {
          bottomTabs: {
            currentTabIndex: 2,
            backgroundColor: theme.COLOR_BOTTOM_NAV_BACKGROUND
          }
        }
      }
    }
  });

As said above if bottomTabs looks like this:

  bottomTabs: {
            currentTabIndex: 2,
            backgroundColor: theme.COLOR_BOTTOM_NAV_BACKGROUND,
            titleDisplayMode: "alwaysShow"
          }

app crashes on Android.

For completeness sake, here is code for generateMainMenu() which generates _main app layout_


generateMainMenu() code:

export function generateMainMenu(): LayoutTabsChildren[] {
  const ICON_PADDING = 1;
  const bottomTabIconOptions: OptionsBottomTab = {
    iconColor: theme.COLOR_BOTTOM_NAV_ICON,
    selectedIconColor: theme.COLOR_BOTTOM_NAV_ICON_ACTIVE,
    textColor: theme.COLOR_BOTTOM_NAV_TEXT,
    selectedTextColor: theme.COLOR_BOTTOM_NAV_TEXT_ACTIVE,
    iconInsets: {
      top: ICON_PADDING,
      bottom: ICON_PADDING,
      right: ICON_PADDING,
      left: ICON_PADDING
    }
  };

  return [
    {
      stack: {
        children: [
          {
            component: {
              name: screenName.FEED_SCREEN
            }
          }
        ],
        options: {
          bottomTab: {
            text: getLocalisedValue("common.menu.feed"),
            icon: iconsList.bottomTabsFeed,
            testID: testID.menu.feed,
            ...bottomTabIconOptions
          }
        }
      }
    },
    {
      stack: {
        children: [
          {
            component: {
              name: screenName.QUICK_WORKOUTS_SCREEN
            }
          }
        ],
        options: {
          bottomTab: {
            text: getLocalisedValue("common.menu.workouts"),
            icon: iconsList.bottomTabsQworkouts,
            testID: testID.menu.workouts,
            ...bottomTabIconOptions
          }
        }
      }
    },
    {
      stack: {
        children: [
          {
            component: {
              name: screenName.WORKOUT_PLANS_SCREEN,
              options: {
                statusBar: {
                  style: "light" as OptionsStatusBar["style"]
                },
                topBar: {
                  ...hiddenTopBarProperties,
                  animate: false
                }
              }
            }
          }
        ],
        options: {
          bottomTab: {
            text: getLocalisedValue("common.menu.plans"),
            icon: iconsList.bottomTabsPlans,
            testID: testID.menu.plans,
            ...bottomTabIconOptions
          }
        }
      }
    },
    {
      stack: {
        children: [
          {
            component: {
              name: screenName.NOTIFICATIONS_SCREEN,
              options: {
                topBar: {
                  title: {
                    text: getLocalisedValue("common.menu.notifications")
                  }
                }
              }
            }
          }
        ],
        options: {
          bottomTab: {
            text: getLocalisedValue("common.menu.notifications"),
            icon: iconsList.bottomTabsNotifications,
            testID: testID.menu.notifications,
            ...bottomTabIconOptions
          }
        }
      }
    },
    {
      stack: {
        children: [
          {
            component: {
              name: screenName.PROFILE_SCREEN
            }
          }
        ],
        options: {
          bottomTab: {
            text: getLocalisedValue("common.menu.profile"),
            icon: iconsList.bottomTabsProfile,
            testID: testID.menu.profile,
            ...bottomTabIconOptions
          }
        }
      }
    }
  ];
}


Environment

  • React Native Navigation version: 6.7.5
  • React Native version: 0.62.2
  • Platform(s) (iOS, Android, or both?): Android
  • Device info (Simulator/Device? OS version? Debug/Release?): Release, multiple Android devices and OS versions
Android acceptebug

All 3 comments

@mralj Hi there :) I can reproduce this problem when I set titleDisplayMode: alwaysHide, worked fine with alwaysShow.

@mralj Hi there :) I can reproduce this problem when I set titleDisplayMode: alwaysHide, worked fine with alwaysShow.

Thanks for taking time to investigate this :)

Migrating from 6.6.2 to 6.11.0 fixed the issue for me

Was this page helpful?
0 / 5 - 0 ratings