【问题标题】:Modify the value of the Tab Bar from a component (react-navigation 6)从一个组件修改Tab Bar的值(react-navigation 6)
【发布时间】:2021-08-21 10:56:36
【问题描述】:

我正在尝试在我的 React Native 应用中实现颜色自定义功能。

我使用 AsyncStorage 存储两个值,主要颜色和次要颜色。每当我加载一个组件时,我都会调用ComponentDidMount() 中的一个函数,该函数获取两个值并更新状态(我的状态有mainColorsecondaryColor 默认设置为undefined,然后它会更新为新的值),并且我的屏幕组件以正确的颜色呈现。这部分代码工作得很好,但我把它放在这里是为了让你有一点上下文。 (如果您认为这效率低下,或者您知道更好的方法,请随时告诉我)

我的问题是我还有一个带有图标的标题按钮,我希望图标的颜色是由 AsyncStorage 存储的值 mainColor 定义的颜色。

我的标题按钮在我的 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 的值,然后渲染应用程序,但我没有设法让它工作,所以我记录了自己并找到了另一种方法:我加载应用程序标题图标的默认颜色(在这种情况下为“#000000”),然后在检索到值后,我从 Counter 组件中对其进行修改。

这就是我所做的:

// 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>
        )
      });

    })()
}

再次,这很好用,我有标题按钮,其颜色定义为mainColor

我想做的最后一件事是:自定义 TabBar 图标的颜色,就像我对标题按钮所做的那样。这就是我遇到问题的地方:我不知道如何从我的组件访问它,而且我在互联网上发现的唯一响应类似问题的东西已经过时了。有人知道我该怎么做吗?

如果我的问题表述不正确,我很抱歉,这是我在此网站上发布的第一个问题。如有必要,请随时建议我如何发布一个好问题。如果你在我的代码中看到一些可怕的东西(一些代码非常错误),也不要犹豫告诉我,我是 React Native 的新手。

感谢您阅读本文:)

【问题讨论】:

    标签: javascript react-native expo react-navigation


    【解决方案1】:

    我猜您有多个导航级别,因此您可以使用 navigation.getParent() 函数 (https://reactnavigation.org/docs/navigation-prop#getparent) 到达另一个导航级别

    所以在你的情况下应该是:

    navigation.getParent().setOptions({..})
    

    实现该行为的另一种方法是将颜色值存储在上下文中,然后所有导航器都可以到达该上下文以应用这些颜色。

    【讨论】:

    • 谢谢您,navigation.getParent() 有效!我不知道我怎么会错过这个:') 我会研究一下你提到的上下文解决方案,因为它看起来很有趣。
    猜你喜欢
    • 2022-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 2017-11-28
    • 2019-10-16
    • 2021-01-25
    相关资源
    最近更新 更多