Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tabs too long (Tab height) #2915

Closed
3 tasks done
599markus opened this issue Sep 4, 2019 · 25 comments
Closed
3 tasks done

Tabs too long (Tab height) #2915

599markus opened this issue Sep 4, 2019 · 25 comments

Comments

@599markus
Copy link

599markus commented Sep 4, 2019

Hi.
Since a while I have the problem that my tabs always take the length of the longest tab ...
With prerenderingSiblingsNumber = {0} (default) it is the case that the first time the
length is right, I change then in Tab 2 or 3, which are longer than the first and then
back again, the first tab is much too long and shows a lot of white space at the end.

I have gone through these following points

Issue Description

node, npm, react-native, react and native-base version, expo version if used, xcode version

Node v11.8.0
npm 6.5.0
react-native 0.58.6
native-base 2.12.0 (same with version 2.13.5)

Expected behaviour

The individual tabs should only be as long as the content

Actual behaviour

The tabs are all as long as the longest tab (in my case, the last tab contains a list and can be very long)

Steps to reproduce

Imports
import {ScrollableTab, Tab, TabHeading, Tabs} from 'native-base';

Inside main View

<Animated.ScrollView
    ref={ref => this._scrollView = ref}
    scrollEventThrottle={5}
    showsVerticalScrollIndicator={false}
    onScroll={Animated.event([{nativeEvent: {contentOffset: {y: this.nScroll}}}], {useNativeDriver: true})}
    style={{zIndex: 0}}
    contentContainerStyle={{paddingTop: this.state.tabIndex > 0 ? HEADER_HEIGHT : IMAGE_HEIGHT}}>
    <Tabs
        // prerenderingSiblingsNumber={0}
        onChangeTab={({i}) => {
            this.setState({contextMenu: {modalVisible: false, callContext: false}});
            // set header height for reading details
            this.animationByClick(i);
            // scroll each tab to top
            this._scrollView.getNode().scrollTo({y: 0, animated: true,});
        }}
        tabBarUnderlineStyle={{backgroundColor: StylingVariables.Colors.main_blue}}
        renderTabBar={(props) => <Animated.View
            style={{
		transform: [{translateY: this.tabY}], 
		zIndex: 1, 
		width: '100%', 
		backgroundColor: 'white', 
		marginBottom: 22,}}>
            <ScrollableTab {...props}
                           tabsContainerStyle={styles.styleTabsContainer}
                           renderTab={(name, page, active, onPress, onLayout) => (
                               <TouchableOpacity key={page}
                                                 onPress={() => onPress(page)}
                                                 onLayout={onLayout}
                                                 activeOpacity={0.4}>
                                   <Animated.View style={{flex: 1, height: 100, backgroundColor: StylingVariables.Colors.white}}>
                                       <TabHeading scrollable
                                                   style={{backgroundColor: 'transparent', paddingLeft: 40, paddingRight: 40, paddingTop: 15,}}
                                                   active={active}>
                                           <Animated.Text style={{
                                               fontFamily: StylingVariables.Fonts.Text.Regular,
                                               color: active ? StylingVariables.Colors.main_blue : StylingVariables.Colors.anthrazite,
                                               fontSize: 16,
                                           }}>
                                               {name}
                                           </Animated.Text>
                                       </TabHeading>
                                   </Animated.View>
                               </TouchableOpacity>
                           )}/>
            <LinearGradient style={styles.shadow} colors={['rgba(0,0,0,0.07)', 'transparent']}/>
        </Animated.View>
        }
	>
		<Tab heading={'Tab1'}>
			<ShortTab/>
		</Tab>
		<Tab heading={'Tab2'}>
			<MiddleTab/>
		</Tab>
		<Tab heading={'Tab3'}>
			<LongTab/>
		</Tab>
    </Tabs>
</Animated.ScrollView>

Is the bug present in both iOS and Android or in any one of them?

both, Android and iOS

Any other additional info which would help us debug the issue quicker.

I also tried wrapping each tab with a content-Tag, but the problem remains the same

@andreeaohno
Copy link

andreeaohno commented Oct 17, 2019

I had this problem too a while ago. Make sure you wrap your Animated.ScrollView in provided by native base (Container should be the first tag in the class you use for the tabs). Also, for the content of each tab to be displayed properly, you need to wrap each child component of each tab in a . This is what worked for me.
For example :
native base fix1.pdf

@lakshaya22
Copy link

I had faced the same issue, I got it fixed by wrapping the Tabs component with the Container of the native-base itself.

In my case i had long list in the 3rd tab so for the 3rd tab I had to specifically put Container style as height of 100% to make it scrollable, 1st and 2nd tab css I kept it as flex:1.

For doing the same i gave the css to Container as

<Container style = {[this.state.tabIndex === 3 ? {height:'100%'} : {flex:1}]}>

This worked for me like a charm.

@hanykumar
Copy link
Contributor

Hi @599markus, please provide minimal snack reproduction for the same.

@waheedakhtar694
Copy link

Same issue here tabs are taking the height of the longest tab, As mentioned here.
ptomasroos/react-native-scrollable-tab-view#415
A fix could be in this
https://github.com/turfaa/react-native-scrollable-tab-view-universal

@pragupnewzera
Copy link

Try something like this,
Fix the height of the parent widget to the maximum screen height you want that Tab Navigator to have.

<ListView or ScrollView>
 <View style={{height:  (width)/(0.8)}} >
    <Tab.Navigator tabBar={(props) => <TabBar {...props} />}>
      <Tab.Screen name="T1" component={T1} />
      <Tab.Screen name="T2" component={T2} />
      <Tab.Screen name="T3" component={T3} />
    </Tab.Navigator>
   </View>
</ ListView or ScrollView>

And for tabs do Something like this

T1 ->

<View style={styles.container}>
  <ScrollView nestedScrollEnabled={true}>
    <FlatList
      numColumns={3}
      data={allMedia}
      keyExtractor={(item) => item.id}
      listKey={(post) => `${post.id}D`}
      renderItem={({ item }) => (Anything)}
      scrollEnabled ={false}
    />
  </ScrollView>
</View>

Remember to disable the scroll view Inside the FlatList of tabs and wrap with a ScrollView with nestedScrollEnabled={true}

@waheedakhtar694
Copy link

@pragupnewzera This will work for the fixed height of the tabs but if the content size is dynamic then content will cut down from bottom after specified height.

@prafgup
Copy link

prafgup commented Jun 11, 2020

@appify-waheed Even if the content in the tabs is dynamic it would be rendered in the scroll view of tabs of given parent height. So basically every tab has height of the given parent (width/0.8 in this case) and nested ScrollView would come into effect afterwards when we try to scroll in the tabs.

@waheed25
Copy link

@prafgup but if nested scroll is enable it is also causing problem while scrolling, sometimes scroll gets stuck with nested scroll.

@prafgup
Copy link

prafgup commented Jun 11, 2020

@waheed25 Scrolling doesnt get stuck if you have manually disabled other scroll views inside the tabs and wrapped whole tab with nested Scroll View.

@waheed25
Copy link

@prafgup could you please give an example. What i did, disabled the inner scroll of the list and add height of on the root view inside the scroll and also nested scroll is enabled so it scrolls only to given height not according to content height.

@pragupnewzera
Copy link

pragupnewzera commented Jun 11, 2020

@prafgup could you please give an example. What i did, disabled the inner scroll of the list and add height of on the root view inside the scroll and also nested scroll is enabled so it scrolls only to given height not according to content height.

Create a createMaterialTopTabNavigator
const Tab = createMaterialTopTabNavigator()

Data used to just render The list view depending upon key

const Data = [
  {
    id: '1'
  },
  {
    id: '2',
    otherData : ......
  },
  {
    id: '3'
  }
]

Renders A List View

const Something = ({ route, navigation , client }) => {
   // Some Functions Getting Data from API

  const renderitem = ({ item }: Props) => {
    if (item.id === '1') {
      return (
      Something
      )
    }
    if (item.id === '2') {
      return (
        Something
              )
           
    }
    return (
    <View style={{height:  (width)/(0.8)}} >
      
      <Tab.Navigator tabBar={(props) => <TabBar {...props} /> } >

        <Tab.Screen name="T1" component={T1 } />
    
        <Tab.Screen name="T2" component={T2} />
        
        <Tab.Screen name="MediaTab" component={MediaTab} />
      </Tab.Navigator>
    </View>
    )
  }

  return (
    <View style={styles.container}>
      <FlatList
        data={Data}
        keyExtractor={(item) => item.id}
        renderItem={renderitem}
        stickyHeaderIndices={[0,2]}      //Try Adding Your Tab Navigator as stickyHeader (Works Without it too)
        listKey={(item) => `${item.id}D`}
      />
    </View>
  )
}

Tabs Similer To This


const MediaTab = ({client}) => {
 // Some Functions Creating MediaList from API
  return (
    <View style={styles.container}>
      <ScrollView nestedScrollEnabled={true}>
        <FlatList
          numColumns={3}
          data={allMedia}
          keyExtractor={(item) => item.id}
          listKey={(post) => `${post.id}D`}
          scrollEnabled ={false}
          renderItem={({ item }) => {
            return item.multimedia_type == "IMAGE" ?
            <Image source={{uri : item.url}} style={styles.image} /> 
            : 
            <Video 
            source={{uri : item.url}} 
            style={styles.image} 
            repeat ={true}
            />
          }}
        />
      </ScrollView>
    </View>
  )
}

All Tabs Height are dynamic , as the lists are fetched from api.

@waheedakhtar694
Copy link

waheedakhtar694 commented Jun 11, 2020

Hi.
Since a while I have the problem that my tabs always take the length of the longest tab ...
With prerenderingSiblingsNumber = {0} (default) it is the case that the first time the
length is right, I change then in Tab 2 or 3, which are longer than the first and then
back again, the first tab is much too long and shows a lot of white space at the end.

I have gone through these following points

Issue Description

node, npm, react-native, react and native-base version, expo version if used, xcode version

Node v11.8.0
npm 6.5.0
react-native 0.58.6
native-base 2.12.0 (same with version 2.13.5)

Expected behaviour

The individual tabs should only be as long as the content

Actual behaviour

The tabs are all as long as the longest tab (in my case, the last tab contains a list and can be very long)

Steps to reproduce

Imports
import {ScrollableTab, Tab, TabHeading, Tabs} from 'native-base';

Inside main View

<Animated.ScrollView
    ref={ref => this._scrollView = ref}
    scrollEventThrottle={5}
    showsVerticalScrollIndicator={false}
    onScroll={Animated.event([{nativeEvent: {contentOffset: {y: this.nScroll}}}], {useNativeDriver: true})}
    style={{zIndex: 0}}
    contentContainerStyle={{paddingTop: this.state.tabIndex > 0 ? HEADER_HEIGHT : IMAGE_HEIGHT}}>
    <Tabs
        // prerenderingSiblingsNumber={0}
        onChangeTab={({i}) => {
            this.setState({contextMenu: {modalVisible: false, callContext: false}});
            // set header height for reading details
            this.animationByClick(i);
            // scroll each tab to top
            this._scrollView.getNode().scrollTo({y: 0, animated: true,});
        }}
        tabBarUnderlineStyle={{backgroundColor: StylingVariables.Colors.main_blue}}
        renderTabBar={(props) => <Animated.View
            style={{
		transform: [{translateY: this.tabY}], 
		zIndex: 1, 
		width: '100%', 
		backgroundColor: 'white', 
		marginBottom: 22,}}>
            <ScrollableTab {...props}
                           tabsContainerStyle={styles.styleTabsContainer}
                           renderTab={(name, page, active, onPress, onLayout) => (
                               <TouchableOpacity key={page}
                                                 onPress={() => onPress(page)}
                                                 onLayout={onLayout}
                                                 activeOpacity={0.4}>
                                   <Animated.View style={{flex: 1, height: 100, backgroundColor: StylingVariables.Colors.white}}>
                                       <TabHeading scrollable
                                                   style={{backgroundColor: 'transparent', paddingLeft: 40, paddingRight: 40, paddingTop: 15,}}
                                                   active={active}>
                                           <Animated.Text style={{
                                               fontFamily: StylingVariables.Fonts.Text.Regular,
                                               color: active ? StylingVariables.Colors.main_blue : StylingVariables.Colors.anthrazite,
                                               fontSize: 16,
                                           }}>
                                               {name}
                                           </Animated.Text>
                                       </TabHeading>
                                   </Animated.View>
                               </TouchableOpacity>
                           )}/>
            <LinearGradient style={styles.shadow} colors={['rgba(0,0,0,0.07)', 'transparent']}/>
        </Animated.View>
        }
	>
		<Tab heading={'Tab1'}>
			<ShortTab/>
		</Tab>
		<Tab heading={'Tab2'}>
			<MiddleTab/>
		</Tab>
		<Tab heading={'Tab3'}>
			<LongTab/>
		</Tab>
    </Tabs>
</Animated.ScrollView>

Is the bug present in both iOS and Android or in any one of them?

both, Android and iOS

Any other additional info which would help us debug the issue quicker.

I also tried wrapping each tab with a content-Tag, but the problem remains the same

@pragupnewzera could you please make a snack with these native-base components because I think the issue could be in react-native-scrollable-tab-view

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

My implementation is similar as you suggested above I have a native-base Container then I have a ScrollView with nestedScrollEnabled, This ScrollView contains three tabs and every tab have it own FlatList with different height.
I tried every above-mentioned solution but nothing works for me.

@prafgup
Copy link

prafgup commented Jun 12, 2020

@appify-waheed I'll try to make a snack and update here in a few days.

@hanykumar
Copy link
Contributor

duplicate #1501

@Angelk90
Copy link

Angelk90 commented Sep 18, 2020

@andreeaohno: You could post a full example at https://snack.expo.io?

@waheedakhtar694, @prafgup, @waheed25:
Here is an example of what I am trying: https://snack.expo.io/3TIg!455J
If anyone finds a solution let me know.

@juliscotto
Copy link

@Angelk90
did you find a solution to your problem?

@Angelk90
Copy link

@juliscotto : No solution yet.

@alicja-mruk
Copy link

@Angelk90 any update?

@Angelk90
Copy link

@alicja99 : No solution yet.

@Angelk90
Copy link

@599markus, @andreeaohno, @lakshaya22, @hanykumar, @waheedakhtar694, @pragupnewzera, @prafgup, @waheed25, @juliscotto, @alicja99:

I hope I haven't forgotten anyone.
Even after years this problem seems to still persist, I think it is time to understand what the problem is and find a solution.

For those wishing to find the solution here is an example of the problem: https://snack.expo.io/-3wZ2AsKU

Please do not use different code or at least post a complete example on https://snack.expo.io to be able to test it.

With reference to the issue: #1501

@prafgup
Copy link

prafgup commented Jun 11, 2021

@599markus, @andreeaohno, @lakshaya22, @hanykumar, @waheedakhtar694, @pragupnewzera, @prafgup, @waheed25, @juliscotto, @alicja99:

I hope I haven't forgotten anyone.
Even after years this problem seems to still persist, I think it is time to understand what the problem is and find a solution.

For those wishing to find the solution here is an example of the problem: https://snack.expo.io/-3wZ2AsKU

Please do not use different code or at least post a complete example on https://snack.expo.io to be able to test it.

With reference to the issue: #1501

Hey @Angelk90 , thanks for the snack, I have added a hotfix here which almost mimics the required functionality you want - https://snack.expo.io/ir57Y3gfb

The changes were in these lines -

<Container>
        <ScrollView nestedScrollEnabled={true}>
            <FlatGrid
              scrollEnabled={false}
              itemDimension={50}
              data={data}
              renderItem={renderRow}
              style={styles.list}
            />
        </ScrollView>
</Container>

I know this is not the exact required functionality as you would want as you want to collapse the toolbar as soon as scroll starts, the only way I can think of doing that is to add a callback function from CollapsingToolbar to enable nested scroll on the tab when the toolbar is collapsed so the nested scroll can begin.

@Angelk90
Copy link

@prafgup : We can say that a starting point, actually the part of the two tabs info and movies should not flow, which happens.

@prafgup
Copy link

prafgup commented Jun 11, 2021

@prafgup : We can say that a starting point, actually the part of the two tabs info and movies should not flow, which happens.

I didn't get you what you meant by "should not flow" ?
If you want the tabs to stick to the top use FlatList with stickyHeaderIndices={[1,2]} like used here #2915 (comment)

@Angelk90
Copy link

Angelk90 commented Jun 11, 2021

@prafgup : What I mean is that it should scroll the content of the tabs, it shouldn't scroll the tabs themselves as well.
To make you understand look at the image, when you scroll up the tabs must remain fine then at the top and only the contents of them should scroll.

Screenshot_20210611-173626.png

@prafgup
Copy link

prafgup commented Jun 11, 2021

@prafgup : What I mean is that it should scroll the content of the tabs, it shouldn't scroll the tabs themselves as well.
To make you understand look at the image, when you scroll up the tabs must remain fine then at the top and only the contents of them should scroll.

You would have to create custom logic for that like mentioned in end of #2915 (comment)

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

No branches or pull requests