I use setRoot and pass bottomTabs, if bottomTabs contains more than one stack, it will crash, only one stack will works well.
It works good on iOS.
the code of setRoot is:
const bottomTabs = {
children: [
{
stack: {
children: [
{
component: {
name: `${PACKAGE_NAME}.Assets`,
},
},
],
options: {
bottomTab: {
testID: 'TabAssets',
title: t('wallet'),
icon: icon.tabAssetThin,
},
},
},
},
{
stack: {
children: [{
component: {
name: `${PACKAGE_NAME}.Market`,
},
}],
options: {
bottomTab: {
testID: 'TabMarket',
title: t('market'),
icon: icon.tabMarket,
},
},
},
},
],
options: {
bottomTabs: {
visible: true,
animate: true, // Controls wether BottomTabs visibility changes should be animated
currentTabIndex: 0,
// currentTabId: 'currentTabId',
// testID: 'bottomTabsTestID',
drawBehind: true,
translucent: false,
iconInsets: { top: 5, bottom: -5 },
disableIconTint: true, // set true if you want to disable the icon tinting
disableSelectedIconTint: true,
backgroundColor: color.t10,
tabColor: color.t4,
selectedTabColor: color.main,
fontFamily: 'Helvetica',
fontSize: 10,
},
},
}
Navigation.setRoot({
root: {
bottomTabs: bottomTabs,
},
})
the logcat info is below:
06-19 14:37:13.826 28452-28452/org.consenlabs.imtoken E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.consenlabs.imtoken, PID: 28452
java.lang.NullPointerException: Attempt to write to field 'int android.view.ViewGroup$MarginLayoutParams.bottomMargin' on a null object reference
at com.reactnativenavigation.presentation.BottomTabsOptionsPresenter.applyDrawBehind(BottomTabsOptionsPresenter.java:56)
at com.reactnativenavigation.presentation.BottomTabsOptionsPresenter.presentChildOptions(BottomTabsOptionsPresenter.java:41)
at com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsController.mergeChildOptions(BottomTabsController.java:82)
at com.reactnativenavigation.viewcontrollers.StackController.lambda$mergeChildOptions$1$StackController(StackController.java:78)
at com.reactnativenavigation.viewcontrollers.StackController$$Lambda$1.run(Unknown Source:4)
at com.reactnativenavigation.viewcontrollers.ViewController.applyOnParentController(ViewController.java:93)
at com.reactnativenavigation.viewcontrollers.StackController.mergeChildOptions(StackController.java:77)
at com.reactnativenavigation.viewcontrollers.ComponentViewController.lambda$mergeOptions$0$ComponentViewController(ComponentViewController.java:65)
at com.reactnativenavigation.viewcontrollers.ComponentViewController$$Lambda$0.run(Unknown Source:6)
at com.reactnativenavigation.viewcontrollers.ViewController.applyOnParentController(ViewController.java:93)
at com.reactnativenavigation.viewcontrollers.ComponentViewController.mergeOptions(ComponentViewController.java:65)
at com.reactnativenavigation.viewcontrollers.Navigator.mergeOptions(Navigator.java:123)
at com.reactnativenavigation.react.NavigationModule.lambda$mergeOptions$3$NavigationModule(NavigationModule.java:76)
at com.reactnativenavigation.react.NavigationModule$$Lambda$3.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
I have a very similar setup, and it works for me on both iOS and Android. The difference I see is that I am setting the id for the components in the stack...
bottomTabs: {
children: [
{
stack: {
children: [{
component: {
id: "groups",
name: "groups",
options: {
topBar: {
title: {
text: screenLabels.groups
}
}
}
}
}],
options: {
bottomTab: {
title: tabLabels.groups,
icon: require("./assets/images/groups.png")
}
}
}
},
{
stack: {
children: [{
component: {
id: "colors",
name: "welcome",
options: {
topBar: {
title: {
text: screenLabels.colors
}
}
}
}
}],
options: {
bottomTab: {
title: tabLabels.colors,
icon: require("./assets/images/colors.png")
}
}
}
},
{
stack: {
children: [{
component: {
id: "items",
name: "welcome",
options: {
topBar: {
title: {
text: screenLabels.items
}
}
}
}
}],
options: {
bottomTab: {
title: tabLabels.items,
icon: require("./assets/images/items.png")
}
}
}
},
{
stack: {
children: [{
component: {
id: "match",
name: "welcome",
options: {
topBar: {
title: {
text: screenLabels.match
}
}
}
}
}],
options: {
bottomTab: {
title: tabLabels.match,
icon: require("./assets/images/match.png")
}
}
}
}
],
options: {
bottomTabs: {
tabColor: "black",
selectedTabColor: "#3c6df0",
backgroundColor: "white",
fontFamily: "Nunito",
fontSize: 10
}
}
}
@ujwal-setlur
Thanks, I added the id filed, but not works for me.
which version of RNN are you using?
0.55.4, the latest
@ujwal-setlur
Sorry, I mean the react-native-navigation version.
The latest from npmjs
Hey @sapjax
I'm not able to reproduce. Could you PR a failing Detox test?
@guyca @ujwal-setlur
I upgrade to the latest version (2.0.2361), then it works well.
I have similar problem using bottomTabs (RNN@alpha) on Android device. App crashes.
@sapjax @guyca I noticed that icon property is needed on Android devices.
example:
const bottomTabs = {
children: [
{
component: {
name: 'navigation.playground.Comp1',
options: {
bottomTab: {
text: 'Text1',
icon: require('./iconName1.png'),
}
}
},
},
{
component: {
name: 'navigation.playground.Comp2',
options: {
bottomTab: {
text: 'Text2',
icon: require('./iconName2.png'),
}
}
},
}
]
}
@hubertjaruzal
how would i use react-native-vector-icons for the icon?
@jstansbe
async function getIcon(name) {
icon = await Icon.getImageSource(name).then(icon => icon);
return { uri: icon.uri }
}
This function will return path to the icon.
getImageSource return Promise so I used async/await.
Your start function should be also async:
async function start() {...}
Inside start() add: iconList = await getIcon('list'); - Where function param is an icon name.
Then you can use it in your setRoot eg.
bottomTab: {
icon: iconList
}
This solution worked in iOS simulator, but didn't on android device.
I created a separate issue about the Icon-requirement on Android. https://github.com/wix/react-native-navigation/issues/3903
I'm having the same problem on Android. Has anyone got the navigation working with react-native-vector-icons?
@hubertjaruzal great. After adding the icon, android started working. Thanks 馃槃
I same problem:
java.lang.NullPointerException: Attempt to read from field 'int android.view.ViewGroup$MarginLayoutParams.bottomMargin' on a null object reference
at com.reactnativenavigation.presentation.ComponentPresenterBase.applyBottomInset(ComponentPresenterBase.java:18)
at com.reactnativenavigation.viewcontrollers.ComponentViewController.applyBottomInset(ComponentViewController.java:106)
at com.reactnativenavigation.viewcontrollers.-$$Lambda$PdnjwIMOFJug2YGdC1rKp4pGYAA.on(lambda)
at com.reactnativenavigation.utils.CollectionUtils.forEach(CollectionUtils.java:93)
at com.reactnativenavigation.utils.CollectionUtils.forEach(CollectionUtils.java:76)
at com.reactnativenavigation.viewcontrollers.ParentController.applyBottomInset(ParentController.java:175)
at com.reactnativenavigation.viewcontrollers.-$$Lambda$PdnjwIMOFJug2YGdC1rKp4pGYAA.on(lambda)
at com.reactnativenavigation.utils.CollectionUtils.forEach(CollectionUtils.java:93)
at com.reactnativenavigation.utils.CollectionUtils.forEach(CollectionUtils.java:76)
at com.reactnativenavigation.viewcontrollers.ParentController.applyBottomInset(ParentController.java:175)
at com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsController.applyBottomInset(BottomTabsController.java:186)
at com.reactnativenavigation.viewcontrollers.bottomtabs.-$$Lambda$yeWoV8F6YAMT2qdLVg9HcIP0M2A.run(lambda)
at com.reactnativenavigation.utils.ObjectUtils.perform(ObjectUtils.java:10)
at com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsController.onMeasureChild(BottomTabsController.java:173)
at com.reactnativenavigation.views.BehaviourDelegate.onMeasureChild(BehaviourDelegate.java:22)
at com.reactnativenavigation.views.BehaviourDelegate.onMeasureChild(BehaviourDelegate.java:7)
at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:813)
at android.view.View.measure(View.java:18804)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:18804)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18804)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:18804)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18804)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
at android.view.View.measure(View.java:18804)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2112)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1228)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1464)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6060)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.H
package.json
{
"dependencies": {
"@react-native-community/async-storage": "^1.6.2",
"@react-native-community/geolocation": "^2.0.2",
"@react-native-firebase/analytics": "^6.0.0",
"@react-native-firebase/app": "^6.0.0",
"@react-native-firebase/crashlytics": "^6.0.0",
"axios": "^0.18.0",
"eventemitter3": "^3.1.2",
"formik": "^1.3.2",
"immutable": "^4.0.0-rc.12",
"lodash": "^4.17.11",
"moment": "^2.24.0",
"numeral": "^2.0.6",
"react": "16.9.0",
"react-native": "0.61.1",
"react-native-action-button": "^2.8.5",
"react-native-auto-height-image": "^1.0.5",
"react-native-bottom-action-sheet": "^1.0.2",
"react-native-camera": "3.6.0",
"react-native-circular-progress": "^1.0.1",
"react-native-color-matrix-image-filters": "5.2.0",
"react-native-config": "^0.11.5",
"react-native-counter": "git+https://github.com/JEGardner/react-native-counter#a444b60bad6af928372056b456a6d4e15969b64d",
"react-native-device-info": "^0.24.3",
"react-native-dropdownalert": "^3.7.1",
"react-native-fbsdk": "1.0.4",
"react-native-image-crop-picker": "^0.25.2",
"react-native-image-header-scroll-view": "^0.10.1",
"react-native-image-progress": "^1.1.1",
"react-native-iphone-x-helper": "^1.2.1",
"react-native-keyboard-aware-scroll-view": "0.9.1",
"react-native-masked-text": "^1.9.2",
"react-native-modal-dropdown": "0.6.2",
"react-native-navigation": "3.2.0-snapshot.524",
"react-native-onesignal": "3.4.1",
"react-native-scrollable-tab-view": "https://github.com/jayshooo/react-native-scrollable-tab-view.git#6ac253a078c71b0cf143f3f8bd75aee7b4ddde58",
"react-native-status-bar-height": "^2.3.1",
"react-native-svg": "^8.0.8",
"react-native-video": "5.0.2",
"react-native-webview": "^7.2.5",
"react-redux": "^5.1.1",
"redux": "4.0.1",
"redux-axios-middleware": "^4.0.0",
"redux-thunk": "^2.3.0",
"reduxsauce": "^1.1.0",
"slugify": "^1.3.4",
"typesafe-actions": "^4.4.2",
"yup": "^0.26.6"
}
}
const bottomTabs = {
children: [
{
stack: [
{
children: [
{
component: { name: "HOME_HOME", id: "ID_OTHER", passProps: { navType: "ROOT", tabIndex: 0 } },
},
{
component: { name: "NEWS_NEWS_LIST", id: "NEWS_LIST_COMPONENT_ID", passProps: { navType: "SUB_PAGE", tabIndex: 0 } },
},
{
component: { id: "ID_OTHER", name: "USER_PROFILE_UPDATE" },
}
],
options: {
bottomTab: { icon: 8, iconColor: "#B3B3B3", selectedIconColor: "#1A783D", selectedTextColor: "#1A783D" },
},
}
]
}
],
id: 'BOTTOM_TAB',
options: {
bottomTabs: {
animate: false,
currentTabIndex: 0,
drawBehind: true,
visible: false,
}
}
}
Navigation.setRoot({ root: { bottomTabs } })
Most helpful comment
@sapjax @guyca I noticed that
iconproperty is needed on Android devices.example: