React Navigation TabBarIcon not appearing

Refresh

November 2018

Views

735 time

1

I can't get a TabBarIcon to appear in my TabNavigator. I've read a bunch of posts from people with a similar issue, but their solutions don't work for me. I'd really just like to be able to have a PNG image component for each TabBarIcon but it just won't appear.

const Tabs = TabNavigator({
    Feed: {
      screen: FeedPage,
      navigationOptions: {
        tabBarLabel:"Feed",
        tabBarIcon: () => (<Image source={require('./Resources/Images/TabBar Icons_Feed.png')} style={{height: 10, width: 10}} />)
      }
    },
    Me: {
      screen: MePage,
      navigationOptions: {
        tabBarLabel:"Me",
      }
    },
  },
  {
    initialRouteName: 'Me',
    tabBarOptions: {
      showIcon: true,
      showLabel: true
    }
  }
);

const RootStack = StackNavigator(
  {
    //All Tabs
    Tabs: {
      screen: Tabs,
    },
    //Other Pages
    Signup: {
      screen: SignupPage,
    },
    ProfilePicUploader: {
      screen: ProfilePicUploaderPage,
    },
    Login: {
      screen: LoginPage,
    },
    User: {
      screen: UserPage,
    },
    EasterEgg: {
      screen: EasterEggPage,
    },
  },
  {
    initialRouteName: 'Tabs',
    headerMode: 'none'
  }
);

export default class App extends Component<Props> {
  render() {
    return (
      <RootStack/>
    );
  }
}

Anyone know what's going on?

3 answers

1

Could you try this one? This is my setup:

const PrimaryNav = TabNavigator({
  ['app/t1']: { screen: T1 },
  ['app/t2']: { screen: T2 },
}, {
  headerMode: 'none',
  initialRouteName: 'app/t1',
  navigationOptions: ({ navigation }) => ({
    tabBarIcon: ({ focused, tintColor }) => {
      const { routeName } = navigation.state;
      if (routeName === 'app/t1') {
        return <Icon name="event-note" color={tintColor} />;
      } else if (routeName === 'app/t2') {
        return <Icon name="place" color={tintColor} />;
      }
      return null;
    },
  }),
  tabBarOptions: {
    showIcon: true,
    showLabel: false,
    activeTintColor: ApplicationStyles.screen.header.tintColor,
    inactiveTintColor: ApplicationStyles.screen.header.inactiveTintColor,
    style: {
      backgroundColor: ApplicationStyles.screen.header.backgroundColor,
    },
  }
})

<Icon> is the react-native-material-ui icon, but Image should work as well.

1

I have setup a smallest possible example to show image on tabs instead of icons have a look on this expo snack. Don't use resizeMode or spaces in the image file name as you are using TabBar Icons_Feed.png. Just import the file and use it with proper height and width, e.g.

import Icon_Feed from './Resources/Images/TabBar_Icons_Feed.png'; 

and use it like this

tabBarIcon: () => (
    <Image source={Icon_Feed} style={{ height: 20, width: 20 }} />
),

OR

You can use require if you want to e.g.

tabBarIcon: () => (
    <Image source={require('./Resources/Images/TabBar_Icons_Feed.png')} style={{ height: 20, width: 20 }} />
),

Read this image guide by react native official documentation to get the possible ways to manage image and properly display it according to your needs.

2

You just need make sure that your file doesn't have whitespace name. So change TabBar Icons_Feed.png to TabBar_Icons_Feed.png. Because android or ios will find name like /xxxx/Resources/Images/TabBar%20Icons_Feed.png. This actually the packager does the job. See here:

The image name is resolved the same way JS modules are resolved. In the example above, the packager will look for my-icon.png in the same folder as the component that requires it. Also, if you have my-icon.ios.png and my-icon.android.png, the packager will pick the correct file for the platform.


Check Valid/Correct Path File

if you see .expo/packager-info.json:

{
  "expoServerPort": 19000,
  "packagerPort": 19001,
  "packagerPid": 84703
}

as you see the port packager is 19001, then you can access your file by http://127.0.0.1:19001/Resources/Images/TabBar Icons_Feed.png (make sure you already running app) in browser. You can make sure all path file is correct.


Permit on Android

Also, if you are using expo for development, make sure you set permission to write drawer for android (source).

enter image description here


Best Practice

I usually use import image like this:

import Icon_Feed from './Resources/Images/TabBarIcons_Feed.png';

...

tabBarIcon: () => (
    <Image
        source={Icon_Feed}
        style={styles.stretch}
        />
)

It works and more readable.