[英]React Native - Move Tab Bar with Screens
我的靈感來自 Up Bank 中的選項卡導航,您可以在此處看到這篇文章的一半左右。
目前我正在使用React Native Material Top Tab Navigator ,它有一個 position 屬性,可以從 Navigator 組件傳遞到位於屏幕上方的 Tab Bar 中。 因此,我認為對這個位置道具使用插值是讓它發揮作用的最佳方式。
我還在此處找到了這篇文章,我發現它是推動事物發展的非常有用的資源。 盡管如此,我還是不能完全讓屏幕與導航選項卡齊平,尤其是在您添加/刪除頁面時。
我對React Native Gesture Handler有一個想法,但是 Tab Navigator 似乎是建立在這個基礎上的,並且還使用 useLayoutEffect 和其他掛鈎來獲取選項卡元素的位置並在更改時更新它。 目前我覺得插值是要走的路,但很高興被證明是錯誤的(如果我被證明是錯誤的工作解決方案更好)。
我當前的代碼:
const Tab = createMaterialTopTabNavigator();
const { width } = Dimensions.get("screen");
export const TabNavBar = ({
state,
navigation,
position,
}: MaterialTopTabBarProps): JSX.Element => {
const [tabPostion, setTabPosition] = React.useState(0);
const routes = state.routes.length;
const tabDifference = width / routes;
const inputRange = [
state.index - routes,
state.index,
state.index,
state.index + routes,
];
const translateXPosition = position.interpolate({
inputRange,
outputRange: [tabDifference, -37.5, -37.5, -tabDifference],
});
React.useEffect(() => {
setTabPosition(translateXPosition);
}, []);
return (
<View
style={{
paddingTop: 50,
flexDirection: "row",
height: 100,
backgroundColor: "white",
}}
>
<Animated.View
style={{
flex: 1,
flexDirection: "row",
alignItems: "center",
transform: [{ translateX: tabPostion }],
position: "absolute",
left: "25%",
top: 50,
}}
>
{state.routes.map((route, index) => {
const label = route.name;
return (
<TouchableOpacity
key={index}
style={{ position: "relative", paddingHorizontal: 20 }}
>
<Animated.Text>{label}</Animated.Text>
</TouchableOpacity>
);
})}
</Animated.View>
</View>
);
};
function TabNavigator() {
return (
<Tab.Navigator
initialRouteName="TabTwo"
tabBar={(props) => <TabNavBar {...props} />}
>
<Tab.Screen name="TabOne" component={TabOneScreen} />
<Tab.Screen name="TabTwo" component={TabTwoScreen} />
<Tab.Screen name="TabThree" component={TabThreeScreen} />
<Tab.Screen name="TabFour" component={TabFourScreen} />
<Tab.Screen name="TabFive" component={TabFiveScreen} />
</Tab.Navigator>
);
}
神速啦。 任何幫助是極大的贊賞!
用非任意數字替換-37.5
應該可以解決您的問題。 除非你有任何死區,否則你應該能夠將你的輸入設置為從0
到你擁有的屏幕數。
對於輸出值,您可以使用希望屏幕出現在第一頁上的位置,最大值是標簽欄出現在最終屏幕上的位置。
一個例子看起來像這樣:
const Tab = createMaterialTopTabNavigator();
const { width } = Dimensions.get("screen");
export const TabNavBar = ({
state,
navigation,
position,
}: MaterialTopTabBarProps): JSX.Element => {
const [tabPostion, setTabPosition] = React.useState(0);
const routes = state.routes.length;
const tabDifference = width / routes;
const inputRange = [
0, // First Screen
routes // Final Screen
];
const translateXPosition = position.interpolate({
inputRange,
outputRange: [tabDifference, tabDifference * routes],
});
React.useEffect(() => {
setTabPosition(translateXPosition);
}, []);
return (
<View
style={{
paddingTop: 50,
flexDirection: "row",
height: 100,
backgroundColor: "white",
}}
>
<Animated.View
style={{
flex: 1,
flexDirection: "row",
alignItems: "center",
transform: [{ translateX: tabPostion }],
position: "absolute",
left: "25%",
top: 50,
}}
>
{state.routes.map((route, index) => {
const label = route.name;
return (
<TouchableOpacity
key={index}
style={{ position: "relative", paddingHorizontal: 20 }}
>
<Animated.Text>{label}</Animated.Text>
</TouchableOpacity>
);
})}
</Animated.View>
</View>
);
};
function TabNavigator() {
return (
<Tab.Navigator
initialRouteName="TabTwo"
tabBar={(props) => <TabNavBar {...props} />}
>
<Tab.Screen name="TabOne" component={TabOneScreen} />
<Tab.Screen name="TabTwo" component={TabTwoScreen} />
<Tab.Screen name="TabThree" component={TabThreeScreen} />
<Tab.Screen name="TabFour" component={TabFourScreen} />
<Tab.Screen name="TabFive" component={TabFiveScreen} />
</Tab.Navigator>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.