React Native - 动态更改选项卡导航器中的背景颜色

Posted

技术标签:

【中文标题】React Native - 动态更改选项卡导航器中的背景颜色【英文标题】:React Native - Change background color in tabnavigator dynamically 【发布时间】:2018-08-08 03:48:29 【问题描述】:

我想根据我的 API 响应动态更改我的标签导航器背景颜色,所以下面是我的代码

_TabNavigator.js

const MyTabnav = TabNavigator(
ScreenOne: 
    screen: ( navigation, screenProps ) => <ScreenOneNav screenProps= tabbarNavigation: navigation, ...screenProps  onNavigationStateChange=null />,
    navigationOptions: 
        tabBarLabel: 'ScreenOne',
        tabBarIcon: ( tintColor ) => (
            <View style=[styles.tabViewBox]>
                 <Text style=[styles.tabText,  color: tintColor ]>ScreenOne</Text>
            </View>
        )
    
,
ScreenTwo: 
    screen: ( navigation, screenProps ) => <ScreenOneNav screenProps= tabbarNavigation: navigation, ...screenProps,  onNavigationStateChange=null />,
    navigationOptions: 
        tabBarLabel: 'ScreenOne',
        tabBarIcon: ( tintColor ) => (
            <View style=[styles.tabViewBox]>
                <Text style=[styles.tabText,  color: tintColor ]>ScreenTwo</Text>
            </View>
        )
    
,
ScreenThree: 
    screen: ( navigation, screenProps ) => <StockNotificationNav screenProps= tabbarNavigation: navigation, ...screenProps  onNavigationStateChange=null />,
    navigationOptions: 
        tabBarLabel: 'Notifications',
        tabBarIcon: ( tintColor ) => (
            <View style=[styles.tabViewBox]>
                 <Text style=[styles.tabText,  color: tintColor ]>ScreenThree</Text>
            </View>
        )
    
,
,
 

    tabBarOptions: 

        style: 
            backgroundColor: white,
            height: 55,
            borderTopColor: 'transparent',
            borderTopWidth: 1,
            paddingRight: 10,
            paddingLeft: 10,
            borderTopWidth: 1,
            borderTopColor: grayPlaceHolder
        ,
        showLabel: false,
        showIcon : true,
    ,
    tabBarComponent : TabBarBottom,

    initialRouteName: 'ScreenTwo',
    tabBarPosition: 'bottom',
    animationEnabled: false,
    swipeEnabled: false
, []);


var styles = StyleSheet.create(
tabText: 
    fontSize: 10,
    fontWeight: "600",
    flex: 4,
,
tabViewBox: 
    flex: 1,
    alignItems: "center",
,
 tabIcon: 
    flex: 5,
    alignSelf: "center",
    marginTop: 10
  ,
);
export default StocksTabNav;

我想在我的 ScreenTwo.js 文件中更改我的 tabnavigtor 背景颜色,其中包含 API 响应代码,因为它 tabnavigator 背景颜色 (backgroundColor) 应该根据 API 更改为黑色或白色响应所以我怎么能做到这一点?你的所有建议都很有价值

根据 Rahul 建议更新代码后给出以下警告消息

【问题讨论】:

【参考方案1】:

您可以做的是制作一个自定义 tabBar 组件,并使用 javascript 不变性概念,您可以覆盖 tabBarOptions 的样式。

     const MyTabnav = TabNavigator(ScreenOne: 
        screen: ( navigation, screenProps ) => <ScreenOneNav screenProps= tabbarNavigation: navigation, ...screenProps  onNavigationStateChange=null />,
        navigationOptions: 
            tabBarLabel: 'ScreenOne',
            tabBarIcon: ( tintColor ) => (
                <View style=[styles.tabViewBox]>
                     <Text style=[styles.tabText,  color: tintColor ]>ScreenOne</Text>
                </View>
            )
        
    ,
    ScreenTwo: 
        screen: ( navigation, screenProps ) => <ScreenOneNav screenProps= tabbarNavigation: navigation, ...screenProps,  onNavigationStateChange=null />,
        navigationOptions: 
            tabBarLabel: 'ScreenOne',
            tabBarIcon: ( tintColor ) => (
                <View style=[styles.tabViewBox]>
                    <Text style=[styles.tabText,  color: tintColor ]>ScreenTwo</Text>
                </View>
            )
        
    ,
    ScreenThree: 
        screen: ( navigation, screenProps ) => <StockNotificationNav screenProps= tabbarNavigation: navigation, ...screenProps  onNavigationStateChange=null />,
        navigationOptions: 
            tabBarLabel: 'Notifications',
            tabBarIcon: ( tintColor ) => (
                <View style=[styles.tabViewBox]>
                     <Text style=[styles.tabText,  color: tintColor ]>ScreenThree</Text>
                </View>
            )
        
    ,
    ,
     

        tabBarOptions: 

            style: 
                backgroundColor: white,
                height: 55,
                borderTopColor: 'transparent',
                borderTopWidth: 1,
                paddingRight: 10,
                paddingLeft: 10,
                borderTopWidth: 1,
                borderTopColor: grayPlaceHolder
            ,
            showLabel: false,


         showIcon : true,
        ,

//Here Goes Your CustomTabBar Component 
        tabBarComponent : CustomTabBarComponent,
        initialRouteName: 'ScreenTwo',
        tabBarPosition: 'bottom',
        animationEnabled: false,
        swipeEnabled: false
    , []);

CustomTabBarComponent.js

     const TabBar = (props) => 
          const  navigationState  = props;
          let newProps = props;

            newProps = Object.assign(
              ,
              props,
              
                style: 

         // get value from redux store and set it here 
                  backgroundColor: 'rgba(0,0,0,0.1)',
                  position: 'absolute',
                  bottom: 0,
                  left: 0,
                  right: 0
                ,
                activeTintColor: '#fff',
                inactiveTintColor: '#bbb',
              ,
            );


          return <TabBarBottom ...newProps />;
        ;

现在您可以将此 CustomTabBarComponent 与 Redux 存储连接,并可以更改您想要的任何属性的值。

【讨论】:

你到底在哪里得到错误?如果没有看到您的代码,很难知道出了什么问题。如果您尝试完全相同的代码,它不会给您错误。即使集成了 redux,它也对我有用。 好的,让我再试试这个场景。 在可能的情况下 ScreenOne 是 stack navigator ,从那个 stacknavigators 第一个屏幕我想更改 tabnavigators 颜色,我该怎么办?我正在使用 createMaterialBottomtabnavigator【参考方案2】:

您需要做的是将标签组件设置为函数并将颜色作为参数发送给该函数。试试这个:

const MyTabnav = color => TabNavigator(
    ScreenOne: 
        screen: ( navigation, screenProps ) => <ScreenOneNav screenProps= tabbarNavigation: navigation, ...screenProps  onNavigationStateChange=null />,
        navigationOptions: 
            tabBarLabel: 'ScreenOne',
            tabBarIcon: ( tintColor ) => (
                <View style=[styles.tabViewBox]>
                    <Text style=[styles.tabText,  color: tintColor ]>ScreenOne</Text>
                </View>
             )
        
    ,
    ScreenTwo: 
        screen: ( navigation, screenProps ) => <ScreenOneNav screenProps= tabbarNavigation: navigation, ...screenProps,  onNavigationStateChange=null />,
        navigationOptions: 
            tabBarLabel: 'ScreenOne',
            tabBarIcon: ( tintColor ) => (
                <View style=[styles.tabViewBox]>
                   <Text style=[styles.tabText,  color: tintColor ]>ScreenTwo</Text>
                </View>
             )
        
    ,
    ScreenThree: 
        screen: ( navigation, screenProps ) => <StockNotificationNav screenProps= tabbarNavigation: navigation, ...screenProps  onNavigationStateChange=null />,
        navigationOptions: 
            tabBarLabel: 'Notifications',
            tabBarIcon: ( tintColor ) => (
                <View style=[styles.tabViewBox]>
                     <Text style=[styles.tabText,  color: tintColor ]>ScreenThree</Text>
                </View>
            )
        
    ,
,


    tabBarOptions: 
        //use the color you passed in the prop here:
        style: 
            backgroundColor: color,
            height: 55,
            borderTopColor: 'transparent',
            borderTopWidth: 1,
            paddingRight: 10,
            paddingLeft: 10,
            borderTopWidth: 1,
            borderTopColor: grayPlaceHolder
        ,
        showLabel: false,
        showIcon : true,
    ,
    tabBarComponent : TabBarBottom,

    initialRouteName: 'ScreenTwo',
    tabBarPosition: 'bottom',
    animationEnabled: false,
    swipeEnabled: false
    , []);


var styles = StyleSheet.create(
    tabText: 
        fontSize: 10,
        fontWeight: "600",
        flex: 4,
    ,
    tabViewBox: 
        flex: 1,
        alignItems: "center",
    ,
    tabIcon: 
        flex: 5,
        alignSelf: "center",
        marginTop: 10
    ,
);
export default MyTabNav;

然后在您使用 MyTabnav 的地方将颜色作为参数传递给它。例如

export default class App extends Component<> 
    constructor(props) 
        super(props);
        this.state = 
            color: 'black'
        ;
    
    getRandomColor = () => 
        var letters = '0123456789ABCDEF';
        var color = '#';
        for (var i = 0; i < 6; i++) 
            color += letters[Math.floor(Math.random() * 16)];
        
        return color;
    ;
    onPress = () => 
        this.setState(
            color: this.getRandomColor()
        );
    ;
    render() 
        const Tabs = MyTabnav(this.state.color);
        return (
            <View style= flex: 1 >
                <Button onPress=this.onPress title="Click me" />
                <Tabs />
            </View>
        );
    

【讨论】:

我尝试了你的代码,但我收到警告消息屏幕,如上检查我的问题部分 你有没有像这样初始化你的标签组件:const Tabs = MyTabnav(this.state.color); 是的,我在我的子 js 文件中初始化它 https://pastebin.com/S7Vk8XmN 检查此链接,我试过这样,当我尝试使用此代码时,我得到空白屏幕并给出黄色警告屏幕 StocksTabNav 与我在问题中提到的 MyTabnav 相同,代码没有任何变化【参考方案3】:

尝试使用

const tabBarOptions = 
// setting height 'null', and top 0 will change the color of pressed tab
   indicatorStyle: 
     height: null,
     top: 0,
     backgroundColor: "red",
     borderBottomColor: "black",
     borderBottomWidth: 3,
   ,
   activeTintColor: "black",
   pressColor: "white",
   style: 
     backgroundColor: "#ddc8be",
   ,
   labelStyle:  fontSize: 13 ,
;

【讨论】:

以上是关于React Native - 动态更改选项卡导航器中的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式反应导航更改选项卡顺序

在 React Native 中始终显示底部选项卡导航器 React Navigation 5

React Native Router Flux 选项卡导航不显示特定组件的选项卡图标

react-native-tab-view 从反应导航屏幕跳转到特定选项卡

能够覆盖 react-native-navigation 的默认选项卡导航堆栈行为

React Native - 尝试在反应导航中创建一个带有选项卡导航器的抽屉,而不呈现选项卡的抽屉项目