如何从 React 导航 BottomTabNavigator 显示底部 sheet?
How to display a bottom sheet from React navigation BottomTabNavigator?
如何从 React 导航 BottomTabNavigator 显示底部 sheet?
我想在单击 tabBarIcon(例如在图片中添加按钮)而不是组件时显示 reanimated-bottom-sheet。
我正在使用
<Tab.Screen
name={Name.name_add_application}
component={Add}
options={{
tabBarIcon: ({focused}) => (
<Image source={TK_Add} resizeMode="contain" style={styles.addBtn} />
),
tabBarButton: props => <CustomTabButton {...props} />,
}}
listeners={({navigation}) => ({
tabPress: e => {
e.preventDefault();
navigation.navigate('CreateNew');
},
})}
/>
在const Tab = createBottomTabNavigator();
和
<MainStack.Group
screenOptions={{
headerShown: false,
cardStyle: {backgroundColor: 'rgba(0, 0, 0, 0)'},
cardOverlayEnabled: true,
cardStyleInterpolator: ({current: {progress}}) => ({
cardStyle: {
opacity: progress.interpolate({
inputRange: [0, 0.5, 0.9, 1],
outputRange: [0, 0.25, 0.7, 1],
}),
},
overlayStyle: {
opacity: progress.interpolate({
inputRange: [0, 0.5],
outputRange: [0, 0.25],
extrapolate: 'clamp',
}),
},
}),
}}
mode="modal">
<MainStack.Screen
name="CreateNew"
component={CreateNew}
options={{
animationEnabled: true,
presentation: 'transparentModal',
}}
/>
</MainStack.Group>
在const MainStack = createStackNavigator();
中打开一个模态组件。
但是有点卡顿,白底0.01秒左右,无法滚动(我不想再用这个方法了)。
您尝试使用 the custom tabBar
props 了吗?
这是一个例子:
<Tab.Navigator
tabBar={() => <BottomSheet />}
screenOptions={{ headerShown: false }}
>
<Tab.Screen name={...} component={...} />
<Tab.Screen name={...} component={...} />
<Tab.Screen name={...} component={...} />
</Tab.Navigator
从文件夹的角度来看,你会有这样的东西
./src/navigators/
├──bottom-tabs-navigator.tsx
└──bottom-sheet/
├──bottom-sheet.tsx
└──bottom-tab-bar.tsx
<Tab.Screen
name={translations.logout}
component={HomeScreen}
options={{
tabBarLabel: translations.logout,
tabBarActiveTintColor: appTheme.themeColor,
headerTitleAlign: 'center',
headerStyle:{height: headerHeight},
tabBarLabelStyle: { fontSize: 14 },
tabBarIcon: () => (
<Image source={AppImages.settings} style={CommonStyle.tabBarImage} />
),
}}
listeners={{
tabPress: (e) => {
showLogoutAlert();
e.preventDefault();
},
}}
/>
e.preventDefault(); will prevent from tapping
这是我的解决方案
function MyTabBar({ state, descriptors, navigation }) {
const tabRef = React.createRef();
const fall = new Animated.Value(1);
const renderInner = () => (
<View style={styles.panel}>{/* ButtomSheet body */}</View>
);
const renderHeader = () => (
<View style={styles.header}>{/* ButtomSheet header */}</View>
);
return (
<View style={{ flexDirection: "row" }}>
<BottomSheet
ref={tabRef}
snapPoints={[CONST.HEIGHT * 0.5, 0]}
renderContent={renderInner}
renderHeader={renderHeader}
initialSnap={1}
callbackNode={fall}
enabledGestureInteraction={true}
/>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
// const label =
// options.tabBarLabel !== undefined
// ? options.tabBarLabel
// : options.title !== undefined
// ? options.title
// : route.name;
const isFocused = state.index === index;
const onPress = () => {
switch (index) {
// add button's case ( which I want to show bottom sheet)
case 2:
tabRef.current.snapTo(0);
break;
default:
const event = navigation.emit({
type: "tabPress",
target: route.key,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
break;
}
};
const onLongPress = () => {
navigation.emit({
type: "tabLongPress",
target: route.key,
});
};
const TabIcon = () => {
// custom your tab
};
return (
<Pressable
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{
flex: 1,
alignItems: "center",
backgroundColor: "#fff",
}}
>
<TabIcon />
{/* {label} */}
</Pressable>
);
})}
</View>
);
}
在const Tab = createBottomTabNavigator();
<Tab.Navigator
tabBar={props => <MyTabBar {...props} />}
screenOptions={{headerShown: false}}>
<Tab.Screen name={/* screen name */} component={/* compo */} />
{/* more screens */}
</Tab.Navigator>
如何从 React 导航 BottomTabNavigator 显示底部 sheet?
我想在单击 tabBarIcon(例如在图片中添加按钮)而不是组件时显示 reanimated-bottom-sheet。
我正在使用
<Tab.Screen
name={Name.name_add_application}
component={Add}
options={{
tabBarIcon: ({focused}) => (
<Image source={TK_Add} resizeMode="contain" style={styles.addBtn} />
),
tabBarButton: props => <CustomTabButton {...props} />,
}}
listeners={({navigation}) => ({
tabPress: e => {
e.preventDefault();
navigation.navigate('CreateNew');
},
})}
/>
在const Tab = createBottomTabNavigator();
和
<MainStack.Group
screenOptions={{
headerShown: false,
cardStyle: {backgroundColor: 'rgba(0, 0, 0, 0)'},
cardOverlayEnabled: true,
cardStyleInterpolator: ({current: {progress}}) => ({
cardStyle: {
opacity: progress.interpolate({
inputRange: [0, 0.5, 0.9, 1],
outputRange: [0, 0.25, 0.7, 1],
}),
},
overlayStyle: {
opacity: progress.interpolate({
inputRange: [0, 0.5],
outputRange: [0, 0.25],
extrapolate: 'clamp',
}),
},
}),
}}
mode="modal">
<MainStack.Screen
name="CreateNew"
component={CreateNew}
options={{
animationEnabled: true,
presentation: 'transparentModal',
}}
/>
</MainStack.Group>
在const MainStack = createStackNavigator();
中打开一个模态组件。
但是有点卡顿,白底0.01秒左右,无法滚动(我不想再用这个方法了)。
您尝试使用 the custom tabBar
props 了吗?
这是一个例子:
<Tab.Navigator
tabBar={() => <BottomSheet />}
screenOptions={{ headerShown: false }}
>
<Tab.Screen name={...} component={...} />
<Tab.Screen name={...} component={...} />
<Tab.Screen name={...} component={...} />
</Tab.Navigator
从文件夹的角度来看,你会有这样的东西
./src/navigators/
├──bottom-tabs-navigator.tsx
└──bottom-sheet/
├──bottom-sheet.tsx
└──bottom-tab-bar.tsx
<Tab.Screen
name={translations.logout}
component={HomeScreen}
options={{
tabBarLabel: translations.logout,
tabBarActiveTintColor: appTheme.themeColor,
headerTitleAlign: 'center',
headerStyle:{height: headerHeight},
tabBarLabelStyle: { fontSize: 14 },
tabBarIcon: () => (
<Image source={AppImages.settings} style={CommonStyle.tabBarImage} />
),
}}
listeners={{
tabPress: (e) => {
showLogoutAlert();
e.preventDefault();
},
}}
/>
e.preventDefault(); will prevent from tapping
这是我的解决方案
function MyTabBar({ state, descriptors, navigation }) {
const tabRef = React.createRef();
const fall = new Animated.Value(1);
const renderInner = () => (
<View style={styles.panel}>{/* ButtomSheet body */}</View>
);
const renderHeader = () => (
<View style={styles.header}>{/* ButtomSheet header */}</View>
);
return (
<View style={{ flexDirection: "row" }}>
<BottomSheet
ref={tabRef}
snapPoints={[CONST.HEIGHT * 0.5, 0]}
renderContent={renderInner}
renderHeader={renderHeader}
initialSnap={1}
callbackNode={fall}
enabledGestureInteraction={true}
/>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
// const label =
// options.tabBarLabel !== undefined
// ? options.tabBarLabel
// : options.title !== undefined
// ? options.title
// : route.name;
const isFocused = state.index === index;
const onPress = () => {
switch (index) {
// add button's case ( which I want to show bottom sheet)
case 2:
tabRef.current.snapTo(0);
break;
default:
const event = navigation.emit({
type: "tabPress",
target: route.key,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
break;
}
};
const onLongPress = () => {
navigation.emit({
type: "tabLongPress",
target: route.key,
});
};
const TabIcon = () => {
// custom your tab
};
return (
<Pressable
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{
flex: 1,
alignItems: "center",
backgroundColor: "#fff",
}}
>
<TabIcon />
{/* {label} */}
</Pressable>
);
})}
</View>
);
}
在const Tab = createBottomTabNavigator();
<Tab.Navigator
tabBar={props => <MyTabBar {...props} />}
screenOptions={{headerShown: false}}>
<Tab.Screen name={/* screen name */} component={/* compo */} />
{/* more screens */}
</Tab.Navigator>