从一个组件修改Tab Bar的值(react-navigation 6)
Modify the value of the Tab Bar from a component (react-navigation 6)
我正在尝试在我的 React Native 应用程序中实现颜色自定义功能。
我使用 AsyncStorage 存储两个值,主要颜色和次要颜色。每当我加载一个组件时,我都会在 ComponentDidMount()
中调用一个函数来获取这两个值并更新状态(我的状态默认情况下将 mainColor
和 secondaryColor
设置为 undefined
,然后它会更新为新值),并且我的屏幕组件会以正确的颜色呈现。这部分代码工作得很好,但我把它放在这里是为了让您了解一些上下文。 (如果您认为这效率低下,或者您知道更好的方法,请随时告诉我)
我的问题是我还有一个带有图标的 header 按钮,我希望图标的颜色由 AsyncStorage 存储的值 mainColor
定义。
我的 header 按钮在我的 App.js 文件中定义,它管理所有导航系统(我使用的是 React Navigation 6):
// App.js
import { StatusBar } from 'expo-status-bar';
import React from "react";
import { StyleSheet, Image, TouchableOpacity } from "react-native";
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Counter from './components/Counter.js';
import AddCounter from './components/AddCounter.js';
// Translation module
import * as Localization from 'expo-localization';
import i18n from 'i18n-js';
import { en, fr } from './i18n/supportedLanguages';
i18n.fallbacks = true;
i18n.translations = { en, fr };
i18n.locale = Localization.locale;
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
// All components managed by TabBar
function TabBar() {
return (
<Tab.Navigator
screenOptions={ ({route}) => ({
tabBarActiveBackgroundColor: "#DDDDDD",
tabBarInactiveBackgroundColor: "#FFFFFF",
tabBarShowLabel: false,
tabBarShowIcon: true
})}>
<Tab.Screen
name="CounterTab"
component={Counters}
options= {{
headerShown: false,
tabBarIcon: () => {
return (
<Image
tintColor="#000000"
source={require("./assets/add_counter.png")}
style={styles.icon}
/>
)
}
}} />
</Tab.Navigator>
)
}
// Everything inside the "Counter" tab, which should display the tab bar
function Counters() {
return (
<Stack.Navigator>
<Stack.Screen
name="Counter"
component={Counter}
options={({navigation}) => ({
title: i18n.t('counters.header_text'),
headerRight: () => (
<TouchableOpacity
style={styles.add_counter_header}
onPress={() => navigation.navigate('AddCounter')}>
<Image
style={styles.add_counter_button}
tintColor="#000000" // <- THE VALUE I WANTED TO BE CUSTOMIZABLE
source={require("./assets/add_counter.png")}/>
</TouchableOpacity>
)
})} />
</Stack.Navigator>
)
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
{/*TabBar display*/}
<Stack.Screen
name="TabBar"
component={TabBar}
options={{
headerShown: false
}} />
{/*FROM HERE : every screen that shouldn't display the TabBar*/}
<Stack.Screen
name="AddCounter"
component={AddCounter}
options={{
title: i18n.t('add_counters.header_text'),
tabBarStyle: { display: 'none' }
}} />
</Stack.Navigator>
</NavigationContainer>
)
}
const styles = StyleSheet.create({
icon: {
width: 30,
height: 30,
},
add_counter_header: {
marginRight: 10
},
add_counter_button: {
height: 26,
width: 26
}
});
我首先想到我应该尝试获取 mainColor
的值,然后呈现应用程序,但我没有设法让它工作,所以我记录了自己并找到了另一种方法:我加载使用 header 图标的默认颜色(在这种情况下为“#000000”)的应用程序,然后在检索到值后,我从计数器组件修改它。
这是我所做的:
// Counter.js, the screen that is first rendered when the app launch, and that have an header button
componentDidMount() {
( async () => {
await this._getColors() // this function updates the state with the color values
this.props.navigation.setOptions({
headerRight: () => (
<TouchableOpacity
style={styles.add_counter_header}
onPress={() => navigation.navigate('AddCounter')}>
<Image
style={styles.add_counter_button}
tintColor={this.state.mainColor} // <- I set the color of the header button here
source={require("../assets/add_counter.png")}/>
</TouchableOpacity>
)
});
})()
}
同样,这工作正常,我有 header 按钮,颜色我定义为 mainColor
:
还有一件事是我想做的:自定义 TabBar 图标的颜色,就像我对 Header 按钮所做的那样。这就是我遇到问题的地方:我不知道如何从我的组件访问它,而且我在互联网上发现的唯一响应类似问题的东西已经过时了。有人知道我该怎么做吗?
如果我的问题表达不正确,我很抱歉,这是我 post 在这个网站上的第一个问题。如有必要,请随时告诉我如何 post 一个好问题。如果你在我的代码中看到一些可怕的东西(一些编码错误的东西)不要犹豫告诉我,我是 React Native 的新手。
感谢您阅读本文:)
我猜你有多个导航级别,所以你可以使用 navigation.getParent()
函数到达另一个导航级别 (https://reactnavigation.org/docs/navigation-prop#getparent)
所以在你的情况下应该是:
navigation.getParent().setOptions({..})
另一种实现该行为的方法是将您的颜色值存储在上下文中,然后所有导航器都可以到达该上下文以应用这些颜色。
我正在尝试在我的 React Native 应用程序中实现颜色自定义功能。
我使用 AsyncStorage 存储两个值,主要颜色和次要颜色。每当我加载一个组件时,我都会在 ComponentDidMount()
中调用一个函数来获取这两个值并更新状态(我的状态默认情况下将 mainColor
和 secondaryColor
设置为 undefined
,然后它会更新为新值),并且我的屏幕组件会以正确的颜色呈现。这部分代码工作得很好,但我把它放在这里是为了让您了解一些上下文。 (如果您认为这效率低下,或者您知道更好的方法,请随时告诉我)
我的问题是我还有一个带有图标的 header 按钮,我希望图标的颜色由 AsyncStorage 存储的值 mainColor
定义。
我的 header 按钮在我的 App.js 文件中定义,它管理所有导航系统(我使用的是 React Navigation 6):
// App.js
import { StatusBar } from 'expo-status-bar';
import React from "react";
import { StyleSheet, Image, TouchableOpacity } from "react-native";
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Counter from './components/Counter.js';
import AddCounter from './components/AddCounter.js';
// Translation module
import * as Localization from 'expo-localization';
import i18n from 'i18n-js';
import { en, fr } from './i18n/supportedLanguages';
i18n.fallbacks = true;
i18n.translations = { en, fr };
i18n.locale = Localization.locale;
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
// All components managed by TabBar
function TabBar() {
return (
<Tab.Navigator
screenOptions={ ({route}) => ({
tabBarActiveBackgroundColor: "#DDDDDD",
tabBarInactiveBackgroundColor: "#FFFFFF",
tabBarShowLabel: false,
tabBarShowIcon: true
})}>
<Tab.Screen
name="CounterTab"
component={Counters}
options= {{
headerShown: false,
tabBarIcon: () => {
return (
<Image
tintColor="#000000"
source={require("./assets/add_counter.png")}
style={styles.icon}
/>
)
}
}} />
</Tab.Navigator>
)
}
// Everything inside the "Counter" tab, which should display the tab bar
function Counters() {
return (
<Stack.Navigator>
<Stack.Screen
name="Counter"
component={Counter}
options={({navigation}) => ({
title: i18n.t('counters.header_text'),
headerRight: () => (
<TouchableOpacity
style={styles.add_counter_header}
onPress={() => navigation.navigate('AddCounter')}>
<Image
style={styles.add_counter_button}
tintColor="#000000" // <- THE VALUE I WANTED TO BE CUSTOMIZABLE
source={require("./assets/add_counter.png")}/>
</TouchableOpacity>
)
})} />
</Stack.Navigator>
)
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
{/*TabBar display*/}
<Stack.Screen
name="TabBar"
component={TabBar}
options={{
headerShown: false
}} />
{/*FROM HERE : every screen that shouldn't display the TabBar*/}
<Stack.Screen
name="AddCounter"
component={AddCounter}
options={{
title: i18n.t('add_counters.header_text'),
tabBarStyle: { display: 'none' }
}} />
</Stack.Navigator>
</NavigationContainer>
)
}
const styles = StyleSheet.create({
icon: {
width: 30,
height: 30,
},
add_counter_header: {
marginRight: 10
},
add_counter_button: {
height: 26,
width: 26
}
});
我首先想到我应该尝试获取 mainColor
的值,然后呈现应用程序,但我没有设法让它工作,所以我记录了自己并找到了另一种方法:我加载使用 header 图标的默认颜色(在这种情况下为“#000000”)的应用程序,然后在检索到值后,我从计数器组件修改它。
这是我所做的:
// Counter.js, the screen that is first rendered when the app launch, and that have an header button
componentDidMount() {
( async () => {
await this._getColors() // this function updates the state with the color values
this.props.navigation.setOptions({
headerRight: () => (
<TouchableOpacity
style={styles.add_counter_header}
onPress={() => navigation.navigate('AddCounter')}>
<Image
style={styles.add_counter_button}
tintColor={this.state.mainColor} // <- I set the color of the header button here
source={require("../assets/add_counter.png")}/>
</TouchableOpacity>
)
});
})()
}
同样,这工作正常,我有 header 按钮,颜色我定义为 mainColor
:
还有一件事是我想做的:自定义 TabBar 图标的颜色,就像我对 Header 按钮所做的那样。这就是我遇到问题的地方:我不知道如何从我的组件访问它,而且我在互联网上发现的唯一响应类似问题的东西已经过时了。有人知道我该怎么做吗?
如果我的问题表达不正确,我很抱歉,这是我 post 在这个网站上的第一个问题。如有必要,请随时告诉我如何 post 一个好问题。如果你在我的代码中看到一些可怕的东西(一些编码错误的东西)不要犹豫告诉我,我是 React Native 的新手。
感谢您阅读本文:)
我猜你有多个导航级别,所以你可以使用 navigation.getParent()
函数到达另一个导航级别 (https://reactnavigation.org/docs/navigation-prop#getparent)
所以在你的情况下应该是:
navigation.getParent().setOptions({..})
另一种实现该行为的方法是将您的颜色值存储在上下文中,然后所有导航器都可以到达该上下文以应用这些颜色。