react-native-tab-view icon indicating copy to clipboard operation
react-native-tab-view copied to clipboard

Centering tabs + constant tab width (and indicator width)

Open bartzy opened this issue 4 years ago • 13 comments

Current behaviour

I'm trying to create the following UI for the TabBar, but am having trouble with centering the indicator below the tabs.

Expected result (ignore the icons): image

Actual result (with the code below): image

Expected behaviour

The indicator tab should be aligned with the tabs, even if they're centered.

Code sample

<TabBar
  {...props}
  style={{
    backgroundColor: 'white',
  }}
  tabStyle={{
    width: 80,
    marginHorizontal: 8,
  }}
  contentContainerStyle={{
    justifyContent: 'center',
  }}
  labelStyle={{
    fontSize: 13,
    fontWeight: '600',
    textTransform: 'capitalize',
  }}
  indicatorStyle={{
    height: 3,
    bottom: 6,
    backgroundColor: 'rgb(107,132,243)',
  }}
  activeColor={'rgb(107,132,243)'}
  inactiveColor={'rgb(168,170,199)'}
/>

Your Environment

software version
ios or android either
react-native 0.61.4
react-native-tab-view 2.11.0
react-native-gesture-handler 1.5.2
react-native-reanimated 1.4.0
node 12.3
npm or yarn npm

bartzy avatar Dec 25 '19 12:12 bartzy

Have you solved the problem

qzxqqa avatar Jan 07 '20 11:01 qzxqqa

To do that you can adjust the margin of the indicator like:

Behaviour

Sample

Code Sample

<TabView
  navigationState={navigationState}
  onIndexChange={index =>
    setNavigationState({ ...navigationState, index })
  }
  renderScene={renderScene}
  initialLayout={{ width: Dimensions.get("window").width }}
  renderTabBar={props => (
    <TabBar
      {...props}
      activeColor={colors.blue}
      inactiveColor={colors.lightText}
      indicatorStyle={{
        backgroundColor: colors.blue,
        marginHorizontal: 40,
        width: 140
      }}
      style={{
        backgroundColor: "white",
        shadowOffset: { height: 0, width: 0 },
        shadowColor: "transparent",
        shadowOpacity: 0,
        elevation: 0,
        marginBottom: 8
      }}
      indicatorContainerStyle={{
        width: Dimensions.get("screen").width
      }}
      contentContainerStyle={{
        justifyContent: "center"
      }}
      tabStyle={{ elevation: 0, width: 140 }}
      labelStyle={{ fontSize: 14 }}
      getLabelText={({ route }) => route.title}
    />
  )}
/>

douglasdc avatar Feb 04 '20 17:02 douglasdc

I have an idea. image According to the picture, you can set left to center the indicator like this: indicatorStyle={{ width: w, left: (100 - w) / 2 }}

JungHsuan avatar Mar 15 '20 15:03 JungHsuan

Same issue on RTL

emadhajjar avatar Apr 13 '20 15:04 emadhajjar

Have some issue in here

pisangGoreng avatar Apr 14 '20 13:04 pisangGoreng

On my case, i add margin and padding horizontal where value of paddingHorizontal twice from marginHorizontal in indicatorContainerStyle, like this :

indicatorContainerStyle={{ marginHorizontal: 30, paddingHorizontal: 60 }}

Sample :

<TabBar
  {...props}
  activeColor={'rgba(78,55,178,1)'}
  inactiveColor={'rgba(78,55,178,.5)'}
  indicatorStyle={{ backgroundColor: 'rgba(78,55,178,1)' }}
  indicatorContainerStyle={{ marginHorizontal: 40, paddingHorizontal: 80 }}
  labelStyle={[styles.txtBold, { textTransform: 'capitalize' }]}
  style={{ backgroundColor: '#fff', borderBottomColor: '#eee', borderBottomWidth: 1, elevation: 0 }}
/>

It works for me.

tabBar

ardanfeb avatar May 14 '20 13:05 ardanfeb

I have an idea. image According to the picture, you can set left to center the indicator like this: indicatorStyle={{ width: w, left: (100 - w) / 2 }}

This is the solution. Of course 100 is just a placeholder here. You have to replace it by Dimension.get('window').width / Number of Tabs for it work responsively on all screen widths. So it would become indicatorStyle={{ width: w, left: (Dimensions.get('window').width / Number of tabs - w) / 2 }}

muhammadtaha1998 avatar Aug 15 '20 13:08 muhammadtaha1998

Need this feature too... Any progress about this?

likeSo avatar Jan 20 '22 02:01 likeSo

So far, its possible to add 'left' param to indicatorStyle which is working as 'marginHorizontal' of tabStyle - but does not work on the second tab ... meaning - it will work when tabs has no margin. Screenshot 2022-03-29 at 14 22 46

Screenshot 2022-03-29 at 14 25 02

good-lly avatar Mar 29 '22 12:03 good-lly

I have an idea. image According to the picture, you can set left to center the indicator like this: indicatorStyle={{ width: w, left: (100 - w) / 2 }}

This is the solution. Of course 100 is just a placeholder here. You have to replace it by Dimension.get('window').width / Number of Tabs for it work responsively on all screen widths. So it would become indicatorStyle={{ width: w, left: (Dimensions.get('window').width / Number of tabs - w) / 2 }}

Tried it in 2022, this 1 worked like a charm!

brianwachira avatar Jul 27 '22 15:07 brianwachira

@muhammadtaha1998 this works great, what about the case, where we have a scrollable tab bar?

quicksilverr avatar Oct 21 '22 11:10 quicksilverr

I think this PR solves that issues - https://github.com/satya164/react-native-tab-view/pull/837

Just by giving width: 'auto' to your tab style

quicksilverr avatar Oct 21 '22 12:10 quicksilverr

IndicatorContainerStyle doesn't work tabBarIndicatorContainerStyle: { justifyContent: "center", },

While ContentContainerStyle works as expected tabBarContentContainerStyle: { justifyContent: "center", },

hamol355 avatar Oct 25 '22 06:10 hamol355