我正在尝试在我的应用程序中实现以下布局:
基本上将我的
<BottomTabNavigator/>
的内容渲染在底部工作表内,而地图始终渲染为后面的屏幕。当您在底部工作表周围按 Tab 键时,内容保持不变,但内容会发生变化。
我正在使用 react-navigation 和 @gorhom/bottom-sheet
我能够实现这一目标,但希望获得一些有关如何使用反应导航正确设置它的指导。
我还没有找到官方指南或任何东西,所以我在网上查找,有些人提到创建一个 custom 选项卡栏,在顶部呈现 BottomSheet (这就是我能够实现此布局的方式)。像这样的东西:
const CustomTabBar = props => {
return (
<React.Fragment>
<BottomSheet
snapPoints = {[450, 300, 0]}
renderContent = {this.renderInner}
renderHeader = {this.renderHeader}
/>
<BottomTabBar {...props} />
</React.Fragment>
);
};
然后我会在模式内进行条件渲染以显示不同的屏幕。这确实感觉有点老套,输入导航和状态道具是一场噩梦。
有更好的方法吗?
我尝试将我的
<BottomTab />
包裹在 <BottomSheet />
内,但这似乎不起作用。
自定义标签栏是执行此操作的正确方法吗?
非常感谢任何帮助!
这里的自定义选项卡栏具有底部工作表,它对于所有选项卡屏幕都是相同的,如果我们在自定义底部选项卡组件中管理底部工作表状态,也可能会产生性能问题。
尝试使用下面的示例来实现与上图所示相同的功能。
import React, {
forwardRef,
useEffect,
useImperativeHandle,
useMemo,
useRef,
} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import BottomSheet from '@gorhom/bottom-sheet';
import {GestureHandlerRootView} from 'react-native-gesture-handler';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
const BottomTab = createBottomTabNavigator();
const CustomBottomSheet = forwardRef((myProps, ref) => {
// ref
const bottomSheetRef = useRef<BottomSheet>(null);
// variables
const snapPoints = useMemo(() => ['25%'], []);
useImperativeHandle(
ref,
() => {
return {
open: () => {
bottomSheetRef.current?.expand();
},
close: () => {
bottomSheetRef.current?.close();
},
};
},
[],
);
return (
<BottomSheet ref={bottomSheetRef} snapPoints={snapPoints}>
<View style={styles.centeredContent}>
<Text style={styles.textStyle}>{`inside ${myProps.name}`}</Text>
</View>
</BottomSheet>
);
});
const TabComponent = (props: any) => {
const customBottomSheetRef = useRef<any>(null);
useEffect(() => {
customBottomSheetRef.current?.open();
}, []);
return (
<View style={styles.centeredContent}>
<Text style={styles.textStyle}>{props.route.name}</Text>
<CustomBottomSheet ref={customBottomSheetRef} name={props.route.name} />
</View>
);
};
function App(): JSX.Element {
return (
<GestureHandlerRootView style={styles.safeAreaContainer}>
<SafeAreaProvider style={styles.safeAreaContainer}>
<NavigationContainer>
<BottomTab.Navigator>
<BottomTab.Screen name="home" component={TabComponent} />
<BottomTab.Screen name="search" component={TabComponent} />
<BottomTab.Screen name="explore" component={TabComponent} />
<BottomTab.Screen name="profile" component={TabComponent} />
</BottomTab.Navigator>
</NavigationContainer>
</SafeAreaProvider>
</GestureHandlerRootView>
);
}
const styles = StyleSheet.create({
safeAreaContainer: {
flex: 1,
backgroundColor: 'white',
},
centeredContent: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
textStyle: {
fontSize: 24,
fontWeight: 'bold',
},
});
export default App;
输出: