[英]How to return a function as an Icon React Native
我昨天剛開始學習 React Native,雖然我現在覺得它非常令人惱火,因為我一直在專門為 web 開發,但我真的很喜歡新元素和一切。
我一直在使用帶有 expo 的反應導航底部抽屜,我想知道如何呈現包含我的圖標的函數。
所以我的抽屜是這樣的——
<Tab.Navigator
initialRouteName="Home"
activeColor="#fff"
tabBar={props => <MyTabBar {...props} />}
shifting="false"
sceneContainerStyle={{ marginBottom: 2 }}>
<Tab.Screen name="Home" component={HomeScreen}
options={{
tabBarLabel: '',
tabBarIcon: (() => <LogoutIcon size={20} />)
}}
/>
<Tab.Screen name="Settings" component={LoginScreen} />
<Tab.Screen name="Profile" component={LoginScreen} />
<Tab.Screen name="Logout" component={LoginScreen} />
</Tab.Navigator>
如您所見,我將一個 Icon 組件傳遞到一個我無法在MyTabBar
組件中呈現的屏幕,因為我不確定如何直接呈現一個函數? 如果
function MyTabBar({ state, descriptors, navigation }) {
return (
<View style={{ flexDirection: 'row', position: 'absolute', bottom: 30, right: 20, left: 20, backgroundColor: '#550080', borderRadius: 200, borderWidth: 2, borderColor: '#3c005a', padding: 0 }}>
{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 = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate({ name: route.name, merge: true });
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
console.log(options)
const tabBarIcon = options.tabBarIcon
console.log(tabBarIcon)
return (
<View className='flex-1 p-5 flex-row w-full text-center items-center justify-center border-r border-[#3c005a]'
key={label}>
<TouchableOpacity
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
onPress={onPress}
style={{ flex: 1, alignSelf: 'center', alignContent: 'center', justifyContent: 'center' }}
>
<View className='w-full items-center justify-center mb-2'>
<Text> {tabBarIcon}</Text>**// Trying to render the icon here.**
</View>
</TouchableOpacity>
</View>
);
})}
</View>
);
}
從我的控制台日志中,我可以看出我通過tabBarIcon
選項的屏幕具有以下輸出:
Object {
"headerShown": false,
"tabBarIcon": [Function tabBarIcon],
"tabBarLabel": "",
"tabBarStyle": Object {
"backgroundColor": "purple",
"borderColor": "red",
"borderRadius": 200,
"borderWidth": "2px",
"bottom": 50,
"height": 80,
"left": 20,
"position": "absolute",
"right": 20,
},
}
首先我想說,如果你是 React Native 的新手,你不應該搞亂自定義標簽欄。 這實際上只是為狂野的東西保留的,你在那里的所有造型似乎都可以正常完成。
如果你仍然想使用自定義標簽欄,我要指出的第一件事是在 React Native 中你不能在Text標簽內放置除文本之外的任何內容。 此外,您正在向選項對象傳遞 tabBarIcon 的內聯函數。 因此,您必須調用它。 您正在尋找更像這樣的東西:
<View>
{tabBarIcon()}
<Text>{options.title}</Text>
</View>
對於將來需要此參考的任何人,我通過使用@expo/vector-icons
包使其工作。
這就是我所做的 -
TabBar 組件 -
function MyTabBar({ state, descriptors, navigation }) {
return (
<View style={{ flexDirection: 'row', position: 'absolute', bottom: 30, right: 20, left: 20, backgroundColor: '#550080', borderRadius: 200, borderWidth: 2, borderColor: '#3c005a', padding: 0 }}>
{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 = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
// The `merge: true` option makes sure that the params inside the tab screen are preserved
navigation.navigate({ name: route.name, merge: true });
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
console.log(options)
const tabBarIcon = options.tabBarIcon
console.log(tabBarIcon)
return (
<View className='flex-1 p-4 flex-row w-full text-center items-center justify-center border-r border-[#3c005a]'
key={label}>
<TouchableOpacity
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
onPress={onPress}
style={{ flex: 1, alignSelf: 'center', alignContent: 'center', justifyContent: 'center' }}
>
<View className='w-full items-center justify-center mb-'>
<Ionicons name={tabBarIcon} size={22} color="#ccc" className='text-white bg-black' />
</View>
</TouchableOpacity>
</View>
);
})}
</View>
);
}
主要組件 -
<Tab.Navigator
initialRouteName="Home"
activeColor="#fff"
tabBar={props => <MyTabBar {...props} />}
shifting="false"
screenOptions={{
headerShown: false,
tabBarStyle: {
position: 'absolute',
bottom: 50,
right: 20,
left: 20,
height: 80,
borderRadius: 200,
backgroundColor: 'purple',
borderColor: 'red',
borderWidth: '2px',
},
}}
sceneContainerStyle={{ marginBottom: 2 }}
>
<Tab.Screen name="Home" component={HomeScreen}
options={{
tabBarLabel: 'Home',
showIcon: true,
tabBarIcon: 'home'
}}
/>
</Tab.Navigator>
結果: -
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.