React-native-tab-view: the views don't auto flex Its own height锛宎ll use the heighest view's height

Created on 29 Jul 2019  路  18Comments  路  Source: satya164/react-native-tab-view

Current behaviour

when i have three views which has different height, but all the views use the heighest view鈥榮 height

Expected behaviour

Each view has the height of each view

Code sample

Screenshots (if applicable)

What have you tried

Your Environment

| software | version
| ---------------------------- | -------
| ios or android |
| react-native | 0.60.0
| react-native-tab-view | ^2.9.0
| react-native-gesture-handler | ^1.3.0
| react-native-reanimated | ^1.0.1
| node |
| npm or yarn | yarn

bug

Most helpful comment

I'm also asking if anyone found a solution?

All 18 comments

This is expected behaviour. TabView renders scenes side by side in a flexbox row. If you want to restrict the height, you should set the height of the tabview in style.

@lipei2017 have you managed to fix it?

@satya164

If you want to restrict the height, you should set the height of the tab view in style

but in this case, it will cause performance problems with re-renders.
Wouldn't you think that it's expected behavior for TabView of the library?

This is expected behaviour. TabView renders scenes side by side in a flexbox row. If you want to restrict the height, you should set the height of the tabview in style.

Why we should set height in style?!?! We might have three scenes with different views and flatlist ! That is not systematic!!

Has anyone found any feasible solution?

I'm also asking if anyone found a solution?

Any solution ?

suffering the same issue here x_x

I agree, it's not very usefull to manually set height to views, each view should have his own height. I tried with manually setHeight to te <TabView/> it didn't help.

Maybe @satya164 you can re-consider this issue ?

Has anyone found a solution? I am using version 藛2.10.0.

+1 would be great if the scenes adapts its own height

+1 this is driving me crazy

+1

While I'm not proud of this solution, it seems to work well. Basically it involves getting the height of each tab and setting the height on style and sceneContainerStyle dynamically on tab change. Hopefully this helps some of you and any suggestions on improving this are welcomed!

TabScreenExample.tsx

import React, {useEffect, useState} from 'react';
import {Dimensions} from 'react-native';
import {TabView} from 'react-native-tab-view';
import {Value} from 'react-native-reanimated';

type HeightType = string | number;

let mounted = false;

const TabScreenExample = () => {
    const [index, setIndex] = useState(0);
    const [height, setHeight] = useState<HeightType>('auto');
    const [tab0Height, setTab0Height] = useState<HeightType>('auto');
    const [tab1Height, setTab1Height] = useState<HeightType>('auto');
    const [tab2Height, setTab2Height] = useState<HeightType>('auto');
    const [tab3Height, setTab3Height] = useState<HeightType>('auto');

    useEffect(() => {
        if (!mounted) {
            setCurrentTabHeight(tab0Height);
            mounted = true;
        }
    });

    const position = new Value(0);

    const [routes] = useState([
        {key: 'tab0', title: 'Tab 0'},
        {key: 'tab1', title: 'Tab 1'},
        {key: 'tab2', title: 'Tab 2'},
        {key: 'tab3', title: 'Tab 3'}
    ]);

    const renderScene = ({route}) => {
        switch (route.key) {
            case 'tab0':
                return <TabExample onLayout={(h: number) => setTab0Height(h)} />;
            case 'tab1':
                return <TabExample onLayout={(h: number) => setTab1Height(h)} />;
            case 'tab2':
                return <TabExample onLayout={(h: number) => setTab2Height(h)} />;
            case 'tab3':
                return <TabExample onLayout={(h: number) => setTab3Height(h)} />;
        }
    };

    const setCurrentTabHeight = (newHeight: HeightType) => {
        const deviceHeight = Dimensions.get('window').height;
        const tabHeight = newHeight !== 'auto' && newHeight < deviceHeight ? deviceHeight : newHeight;
        if (height !== tabHeight) {
            setHeight(tabHeight);
        }
    };

    const _onTabChange = (index) => {
        switch (index) {
            case 0:
                setCurrentTabHeight(tab0Height);
                break;
            case 1:
                setCurrentTabHeight(tab1Height);
                break;
            case 2:
                setCurrentTabHeight(tab2Height);
                break;
            case 3:
                setCurrentTabHeight(tab3Height);
                break;
        }
    };

    return (
        <TabView
            style={{height}}
            sceneContainerStyle={{height}}
            navigationState={{index, routes}}
            renderScene={renderScene}
            onIndexChange={(index) => {
                setIndex(index);
                _onTabChange(index);
            }}
            position={position}
            initialLayout={{width: Dimensions.get('window').width}}
        />
    );
};

export default TabScreenExample;

TabExample.tsx

import React from 'react';
import {View} from 'react-native';

interface Props {
    onLayout: (h: number) => void;
}

const TabExample = ({onLayout}: Props) => {
    return (
        <View onLayout={event => onLayout(event.nativeEvent.layout.height)}>
            {/* Tab Content Here */}
        </View>
    );
};

export default TabExample;

@suxur I tried to do the same thing as you but my tabview keeps re-rendering all scenes (tabs) whenever index changes, hence rendering the calculated height pointless.

Did you encounter this?

I believe so and that's why the each tab saves it's height to it's own variable in the state. Then the on change tab should choose the correct height for that tab.

It is hard to manage the FlexBox Equal Column Height default behaviour when you have dynamic and endless FlatLists in your screens. I think the library should offer the way to handle this. I have tried to pass a hidden overflow or a flex-start align to each child but not working. The only way is to dinamically calculate the height, something that can affect performance with large lists.

also experiencing this issue

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hyochan35 picture hyochan35  路  3Comments

t3chnoboy picture t3chnoboy  路  3Comments

AndriiUhryn picture AndriiUhryn  路  3Comments

QuentinBrosse picture QuentinBrosse  路  4Comments

ahmedrowaihi picture ahmedrowaihi  路  3Comments