react-native-scrollable-tab-view
react-native-scrollable-tab-view copied to clipboard
Each tab has the same height if ScrollableTabView is placed inside a ScrollView
I have the following code structure:
<ScrollView>
{header}
<ScrollableTabView>
<View tabLabel="tab1">{smallContent}</View>
<View tabLabel="tab2">{largeContent}</View>
</ScrollableTabView>
</ScrollView>
the problem here is that the smallContent
will have the same scrolling capacity as largeContent
. Maybe someone faced the same issue? I'm also not quite sure whether it is a ScrollableTabView
problem or not.
have the same problem...
main.js
_handleTabHeight(obj){
console.log(this.refs[obj.ref.props.tabLabel].state.name)
this.refs[obj.ref.props.tabLabel].gogogo((x,y,w,h,l,t) => {
if(h!==0){
this.setState({tabViewStyle: {height: h}})
}
})
}
<ScrollableTabView
onChangeTab={(obj) => this._handleTabHeight(obj)}
style={this.state.tabViewStyle}
>
<ReactPage ref='high1' tabLabel="high1" />
<ReactPage2 ref='high2' tabLabel="high2" />
<ReactPage3 ref='high3' tabLabel="high3" />
</ScrollableTabView>
ReactPage.js/ReactPage2.js/ReactPage3.js
gogogo(cb) {
this.refs.test.measure(cb)
}
render() {
return (
<View
ref='test'
style={{
height: 300,
backgroundColor: 'blue'
}}
>
</View>
);
}
}
worked~!
Has it been fixed ?
I has the same problem
+1
+1
@laclys Thanks, your method really works. In addition, when you apply tabViewStyle's height to ScrollableTabView' style, you should plus tabBar's height. And in my practice, you can apply it to contentProps directly. like the following code:
<ScrollableTabView
contentProps={{style:{...tabViewStyle}}}
>
</ScrollableTabView>
#814 #866
Has it been fixed ? Why close this bug?
I have same issue.
Please can we re-open this issue? I don't believe there is a clear solution to the problem? @laclys is very old and I don't believe ref's work like this anymore in react-native?
I'm just adding a comment to this... I'm not 100% sure if I'm correct but I believe this might solve our problem?
<ScrollableTabView style={{ flex: 1 }}>
<FlatList tabLabel="First" contentContainerStyle={{ flexGrow: 1 }} /> // Could be inside a named component...
<FlatList tabLabel="Second" contentContainerStyle={{ flexGrow: 1 }} /> // Could be inside a named component...
</ScrollableTabView>
Yes, this needs to reopen, @laclys answer doesn't work anymore, as this.refs doesn't work like that anymore...
Yeah, This needs to be re-open.
Feel free to send a pr
export const TabContext = createContext({
heightObj: {},
changeState: (tabLabel, height) => { }
})
const TabProvider: FC<Props> = (props) => {
const { children, style = {}, initialPage = 0 } = props
const [heightObj, setHeightObj] = useState<{ [key: string]: number }>({})
const [currentIndex, setCurrentIndex] = useState<number>(0)
const [viewHeight, setViewHeight] = useState<number>(deviceHeight)
const { y, onLayout } = useLayout() //@react-native-community/hooks
const minHeight = deviceHeight - y - 50
const [tabLabelObj] = useState(() => {
const obj = {}
Children.map(children, (item: any, index) => {
obj[index] = item.props.tabLabel
})
return obj
})
useEffect(() => {
setCurrentIndex(0)
}, [])
useEffect(() => {
getHeight()
}, [currentIndex, tabLabelObj])
const changeState = (tabName: string, height: number) => {
heightObj[tabName] = height
setHeightObj(heightObj)
}
const getHeight = () => {
const data = heightObj[tabLabelObj[currentIndex || 0]]
const _height = data > minHeight ? data : minHeight
console.log(_height || deviceHeight)
setViewHeight(_height || deviceHeight)
}
return (
<TabContext.Provider value={{
heightObj,
changeState
}}>
<View style={[style, { height: viewHeight + 50 }]} onLayout={onLayout}>
<ScrollableTabView
renderTabBar={() => <TabContainer {...props} />}
initialPage={initialPage}
prerenderingSiblingsNumber={Infinity}
onChangeTab={({ i }) => {
setCurrentIndex(i)
}}
>
{children}
</ScrollableTabView>
</View>
</TabContext.Provider>
)
}
const TabItem: FC<Props> = ({
style = {},
children,
tabLabel,
}) => {
const { changeState } = useContext(TabContext)
const { height, onLayout } = useLayout() //@react-native-community/hooks
useEffect(() => {
changeState(tabLabel, height)
}, [height])
return (
<View
style={[{ backgroundColor: '#fff' }, style]}
onLayout={onLayout}
>
{children}
</View>
)
}
const Main = () => {
const renderActivity = () => {}
const renderTools = () => {}
const renderUser = () => {}
return (
<TabProvider>
<TabItem tabLabel={'Activity'}>
{renderActivity()}
</TabItem>
<TabItem tabLabel={'Tools'}>
{renderTools()}
</TabItem>
<TabItem tabLabel={'User'}>
{renderUser()}
</TabItem>
</TabProvider>
)
}
I solved it this way A single component is packaged to control all of this, and it is non-intrusive and very simple to the outside
This is how I am using for auto-height issue inside <ScrollView>
onTabIndexChange = (params) => {
this.setState({
index: params.i
});
};
<ScrollView style={{flex: 1}}>
...
<View style={{flex: 1}}>
<ScrollableTabView onChangeTab={this.onTabIndexChange}>
<View tabLabel="First Tab" />
<View tabLabel="Second Tab" />
<View tabLabel="Third Tab" />
</ScrollableTabView>
{0 === this.state.index ? this.firstTab() : null}
{1 === this.state.index ? this.secondTab() : null}
{2 === this.state.index ? this.thirdTab() : null}
</View>
</ScrollView>
This is how I am using for auto-height issue inside
<ScrollView>
onTabIndexChange = (params) => { this.setState({ index: params.i }); }; <ScrollView style={{flex: 1}}> ... <View style={{flex: 1}}> <ScrollableTabView onChangeTab={this.onTabIndexChange}> <View tabLabel="First Tab" /> <View tabLabel="Second Tab" /> <View tabLabel="Third Tab" /> </ScrollableTabView> {0 === this.state.index ? this.firstTab() : null} {1 === this.state.index ? this.secondTab() : null} {2 === this.state.index ? this.thirdTab() : null} </View> </ScrollView>
but you cant scroll horizontal
I need a solution for this, isn't there a solution?
any solution