Skip to content
This repository has been archived by the owner on Nov 27, 2022. It is now read-only.

Android: Nested tab-view doesn't display children #105

Closed
jbrodriguez opened this issue Jan 19, 2017 · 19 comments
Closed

Android: Nested tab-view doesn't display children #105

jbrodriguez opened this issue Jan 19, 2017 · 19 comments

Comments

@jbrodriguez
Copy link

jbrodriguez commented Jan 19, 2017

On Android, there are some issues with ViewPagerAndroid, when it's nested inside a ScrollView.

This is a description of the issue on a similar component:

ptomasroos/react-native-scrollable-tab-view#187

Also, I think this is what the user that opened #24 meant.

If you edit TabViewAnimated.js like this, it works on Android

switch (Platform.OS) {
case 'android':
  // TabViewPager = require('./TabViewPagerAndroid').default;
  // break;
case 'ios':
  TabViewPager = require('./TabViewPagerScroll').default;
  break;
default:
  TabViewPager = require('./TabViewPagerPan').default;
  break;
}
@satya164
Copy link
Owner

I am not sure if there's anything I can do to fix it. you can use the renderPager prop of TabViewAnimated to use TabViewPagerPan without having to edit the files

@jbrodriguez
Copy link
Author

I'll check that out

@Polidoro
Copy link

Polidoro commented Feb 7, 2017

If anyone else is having this problem here's my implementation of the workaround suggested by satya164, loosely based on the ScrollViewExample code here.

Thanks for the tip btw, I was really stuck on this!

import { Platform } from 'react-native'
import { TabViewAnimated, TabViewPagerScroll, TabViewPagerPan, TabBar } from 'react-native-tab-view'

/* ... Omitted for brevity ... */

  _renderPager = (props) => {
   return (Platform.OS === 'ios') ? <TabViewPagerScroll {...props} /> : <TabViewPagerPan {...props} />
  }

  render () {
    return (
      <TabViewAnimated style={styles.container}
        navigationState={this.state}
        renderScene={this._renderScene}
        renderHeader={this._renderHeader}
        onRequestChangeTab={this._handleChangeTab}
        renderPager={this._renderPager}
      />
    )
  }
}

@jasan-s
Copy link

jasan-s commented Apr 28, 2017

@Polidoro thanks for the snippet. nested Tabview on Android is finally functional. :)

@WillyRamirez
Copy link

@satya164 Hi! When I use @Polidoro 's example I get the following error:
"The specified child already has a parent. You must call removiewView() on the child's parent first."

Do you have any idea why this erroris thrown?

@Polidoro
Copy link

Polidoro commented May 2, 2017

Can you paste your code? Also what version of react-native-tab-view are you using (since as jasan-s mentioned the behavior changed recently)

@WillyRamirez
Copy link

@Polidoro thanks for the fast response! this is my class. Basically a copy from the example page.

class Profile extends React.Component {
  state = {
    index: 0,
    routes: [
      { key: '1', title: 'First' },
      { key: '2', title: 'Second' },
      { key: '3', title: 'third' },
    ],
  };

  componentDidMount(){
    Actions.refresh({title: this.props.profile.username});
  }

  _handleChangeTab = (index) => {
    this.setState({ index });
  };

  _renderPager = (props) => {
    return (Platform.OS === 'ios') ? <TabViewPagerScroll {...props} /> : <TabViewPagerPan   {...props} />
  };

  _renderHeader = (props) => {
    return <TabBar {...props} />;
  };

  _renderScene = ({ route }) => {
    switch (route.key) {
      case '1':
        return <ProfileMedia  />;
      case '2':
        return <ProfileFollowers  />;
      case '3':
        return <ProfileWorkoutPlans  />;
      default:
        return null;
    }
  };

  render(){
    return(
      <ScrollView style={styles.mainContainer}>
        <ProfileHeader profile={this.props.profile} />

        <TabViewAnimated navigationState={this.state}
                         renderScene={this._renderScene}
                         renderPager={this._renderPager}
                         renderHeader={this._renderHeader}
                         onRequestChangeTab={this._handleChangeTab}/>

      </ScrollView>
    )
  }
}


export default Profile;

@Polidoro
Copy link

Polidoro commented May 2, 2017

I assume you're on v0.0.61?

Does the error occur on Android too or just iOS? Have you tried swapping the ScrollView out for a regular View to see if that has any impact?

@WillyRamirez
Copy link

WillyRamirez commented May 2, 2017

I was on v0.0.62, downgraded to .61 and it works now! Thanks a bunch @Polidoro
I am using android.
I am experiencing another bug now where the entire app freezes and throws Max Call stack exceeded error when switching tabs after a few taps, but will probably create separate issue.

@satya164
Copy link
Owner

satya164 commented May 3, 2017

Definitely a bug with React Native since I'm not doing any weird stuff here. And I was able to successfully nest it.

@WillyRamirez
Copy link

Are you sure? After diving into this today I found that on the second time I change tabs,
_renderPager, _renderHeader, _renderScene and _handleChangeTab() are in a loop, infinitely being called until the max call stack error stops the loop. _handleChangeTab is even called with different index everytime.

When I wait 30 seconds between each click, this does not occur. Also when I don't use TabViewPagerPan on Android it works just fine..

@satya164
Copy link
Owner

satya164 commented May 3, 2017

"The specified child already has a parent. You must call removiewView() on the child's parent first." doesn't sound like an infinite loop.

Please open a new issue with the code if there is an infinite loop and I'll look into it.

@WillyRamirez
Copy link

@satya164 that was the error I got implementing Polidoro's fix with V 0.0.6.2. With V0.0.6.1 the error was gone, but now I have an inf loop. I'll create a new issue, thanks.

@Polidoro
Copy link

Polidoro commented May 3, 2017

Not sure if this helps clarify but I wrote that snippet well before v0.0.62 was released. v0.0.59 (or around there) made that workaround unnecessary.

@WillyRamirez
Copy link

WillyRamirez commented May 3, 2017

I'll downgrade again, thnx for the headsup. However even if it fixes it, the inf loop is still worth looking into.

@WillyRamirez
Copy link

WillyRamirez commented May 3, 2017

@Polidoro the downgrade fixed it again. V0.0.59 in combination with your implementation above works perfectly!

@satya164 let me know if you want to explore the inf loop with me on V0.0.61. I can create an issue.
The "The specified child already has a parent. You must call removiewView() on the child's parent first." is most likely a React-native issue.

@satya164
Copy link
Owner

satya164 commented May 3, 2017

Please create an issue. I'm on vacation right now, but will look as soon as I get time.

@jasan-s
Copy link

jasan-s commented May 19, 2017

i have not tried this yet but I'm about to switch to react-navigation which uses this lib. @Polidoro , how would I conditional render pagers for it, since I don't think you have direct access to the same props ?

@Polidoro
Copy link

Hi @jasan-s! I'm no expert but you might be able to set conditional rendering by using the lazy prop on TabViewAnimated and then adding conditions to the individual scenes.

If you can explain in more detail what you're trying to accomplish maybe I can be more helpful?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants