React-native-tab-view: [Android only] Cannot use with react-community/react-navigation

Created on 7 Jun 2017  路  16Comments  路  Source: satya164/react-native-tab-view

Not sure if this is react-navigation's problem or react-native-community/react-native-tab-view's problem.

Steps to reproduce

The problem only exist on Android.
Copy and paste the example code of react-native-community/react-native-tab-view and using it inside a scene of react-navigation's TabNavigator.

Expected Behavior

Only using react-native-community/react-native-tab-view on Android:
screenshot_20170607-225933

Using react-native-community/react-native-tab-view with react-navigation on iOS:
ios

Current Behavior

Using react-native-community/react-native-tab-view with react-navigation on Android.

Bugs:

  1. The scene body of react-native-community/react-native-tab-view is not visible.
  2. Scene does not "snap" when swiped, instead it's stuck at where it is swiped.

screenshot_20170607-230006

Your Environment

| software | version
| ---------------- | -------
| react-navigation | [email protected]
| react-native-tab-view | [email protected]
| react-native | [email protected] (using CRNA, expo v = 17.0.0)
| node | v6.2.1
| npm or yarn | 3.10.9

Most helpful comment

@HanAsteroid A temporary (and hacky) fix might be to use the pager that is used for IOS by default:

import {TabViewAnimated, TabViewPagerScroll} from "react-native-tab-view";

<TabViewAnimated
  renderPager={(props) => <TabViewPagerScroll {...props}/>}
/>

Make sure the navigationState is present in props of course.

WARNING

You will notice that scrolling is not as smooth as it would be when using the android pager. You might also notice that you will be able to scroll left/right even while pulling down for RefreshControl, which makes for a pretty bad user experience.

EDIT: Try using TabViewPagerPan instead of TabViewPagerScroll.

All 16 comments

anyone solved it ?
I have the same problem!

@HanAsteroid A temporary (and hacky) fix might be to use the pager that is used for IOS by default:

import {TabViewAnimated, TabViewPagerScroll} from "react-native-tab-view";

<TabViewAnimated
  renderPager={(props) => <TabViewPagerScroll {...props}/>}
/>

Make sure the navigationState is present in props of course.

WARNING

You will notice that scrolling is not as smooth as it would be when using the android pager. You might also notice that you will be able to scroll left/right even while pulling down for RefreshControl, which makes for a pretty bad user experience.

EDIT: Try using TabViewPagerPan instead of TabViewPagerScroll.

Thanks @Palisand it works :)

Even TabViewPagerScroll gives unexpected behaviour, when I have 4+ tabs, after I clicked 4th tab, all the tabs goes unresponsive.

Edit: I found that inside TabViewPagerScroll's _handleScroll function, sometimes e.nativeEvent.contentOffset.x won't be equal to this._nextOffset. (floating point values)
If I wrap both values inside Math.round, it works fine.

@filippofilip95, can you show how to fix it? I have been user renderPager with both TabViewPagerSpan and tabViewPagerScroll but it doesn't work

@vokhuyet, finally i solved it with TabViewPagerPan

<TabViewAnimated
      navigationState={ tabsState }
      renderScene={ renderScene }
      renderHeader={ props => <TabBar { ...props } { ...tabBarStyles } /> }
      onRequestChangeTab={ (index) => setTabsState({ ...tabsState, index }) }
      renderPager={ props => <TabViewPagerPan { ...props } /> }
    />

and with disabling swipe on TabNavigator (required only for android)

const Tabs = TabNavigator(tabRoutes, {
  lazyLoad: false,
  swipeEnabled: false,
  tabBarOptions,
  tabBarPosition: 'bottom',
});

@filippofilip95 thank you for your reply. i have been used
renderPager={ props => }
but tabview scroll very slow between tabItems and when i clicked tabheader tabview scroll after a long time . Do you know this bug ?

@vokhuyet, in my case it works smoothly
ezgif com-video-to-gif

There is my pure component: https://gist.github.com/filippofilip95/960d765b395f8e64086d594149be28d0

and HOC component:
https://gist.github.com/filippofilip95/bc1a2789dbc558ff08482037abeb068c

Hope that helps you.

You could try to use renderScene with switch. https://gist.github.com/filippofilip95/bc1a2789dbc558ff08482037abeb068c#file-petshoc-js-L37
or stop remote JS debugging if you have it turned on.

@filippofilip95 thank you so much. you helped me very much. when i clicked on tab icon , tabview swipe after a delay time. i guess my screen has many views . thus, it's slow

@Palisand that solved my issue. thanks a lot 馃憤

This is a pretty big problem for me at the moment, stuck on white screen of death soon as I swap stackNavigator to TabNavigator.. Anyone else running into this issue?
"react-native": "0.50",
"react-navigation": "1.0.0-beta.19",
"react-native-tab-view": "0.0.70",

EDIT: Fixed!
My problem was due to nesting tabNavigators. If anyone runs into this problem, you need to add in:

  swipeEnabled: false,
  animationEnabled: false,

To at least one of the tabNavigators (for android only)

@ElliottJRo you saved me over 10 hours of debugging. Thanks alot!!!

So I've literally copy pasted the ScrollView example into my project to test it.
The header works but the scene is not visible.

I only changed the Lists into simple views with colored backgrounds.

This is the code, it's the example code with only the scene changed. Is the issue the height like someone had said before in another issue? :

import React, { PureComponent } from 'react';
import { Animated, StyleSheet, View } from 'react-native';
import { TabViewAnimated, TabBar } from 'react-native-tab-view';


import type { Route, NavigationState } from 'react-native-tab-view/types';

type State = NavigationState<
  Route<{
    key: string,
    title: string,
  }>
>;

export default class TopBarTextExample extends PureComponent<*, State> {
  static title = 'Scroll views';
  static backgroundColor = '#fff';
  static tintColor = '#222';
  static appbarElevation = 0;

  state = {
    index: 0,
    routes: [
      { key: '1', title: 'First' },
      { key: '2', title: 'Second' },
      { key: '3', title: 'Third' },
    ],
  };

  _first: ?BasicListView;
  _second: ?BasicListView;
  _third: ?BasicListView;

  _handleIndexChange = index =>
    this.setState({
      index,
    });

  _handleTabItemPress = ({ route }) => {
    if (route !== this.state.routes[this.state.index]) {
      return;
    }
    switch (route.key) {
      case '1':
        if (this._first) {
          this._first.scrollTo({ y: 0 });
        }
        break;
      case '2':
        if (this._second) {
          this._second.scrollTo({ y: 0 });
        }
        break;
      case '3':
        if (this._third) {
          this._third.scrollTo({ y: 0 });
        }
        break;
    }
  };

  _renderLabel = props => ({ route, index }) => {
    const inputRange = props.navigationState.routes.map((x, i) => i);
    const outputRange = inputRange.map(
      inputIndex => (inputIndex === index ? '#D6356C' : '#222')
    );
    const color = props.position.interpolate({
      inputRange,
      outputRange,
    });

    return (
      <Animated.Text style={[styles.label, { color }]}>
        {route.title}
      </Animated.Text>
    );
  };

  _renderHeader = props => (
    <TabBar
      {...props}
      pressColor="rgba(255, 64, 129, .5)"
      onTabPress={this._handleTabItemPress}
      renderLabel={this._renderLabel(props)}
      indicatorStyle={styles.indicator}
      tabStyle={styles.tab}
      style={styles.tabbar}
    />
  );

  _renderScene = ({ route }) => {
    switch (route.key) {
      case '1':
        return (
          <View
            style={[styles.page, { backgroundColor: '#E3F4DD' }]}>
          </View>
        );
      case '2':
        return (
          <View

            style={[styles.page, { backgroundColor: '#E6BDC5' }]}>

          </View>
        );
      case '3':
        return (
          <View

            style={[styles.page, { backgroundColor: '#EDD8B5' }]}>

          </View>
        );
      default:
        return null;
    }
  };

  render() {
    return (
      <TabViewAnimated
        style={[styles.container, this.props.style]}
        navigationState={this.state}
        renderScene={this._renderScene}
        renderHeader={this._renderHeader}
        onIndexChange={this._handleIndexChange}
      />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    height: 400,
  },
  indicator: {
    backgroundColor: '#ff4081',
  },
  label: {
    fontSize: 13,
    fontWeight: 'bold',
    margin: 8,
  },
  tabbar: {
    backgroundColor: '#fff',
  },
  tab: {
    opacity: 1,
    width: 90,
  },
  page: {
    backgroundColor: '#f9f9f9',
  },
});

Is this still an issue? I'm not experiencing this anymore (on both platforms) with the default pagers after upgrading to the latest versions of react-navigation and react-native-tab-view.
@satya164 Consider closing?

Set lazy: true and you are good to go

Was this page helpful?
0 / 5 - 0 ratings

Related issues

f6m6 picture f6m6  路  3Comments

KingAmo picture KingAmo  路  3Comments

t3chnoboy picture t3chnoboy  路  3Comments

ashusdn picture ashusdn  路  4Comments

hyochan35 picture hyochan35  路  3Comments