想实现一个更换 app 整体色调(导航头,tabBar 以及按钮)的功能,比如在晚上可以换成黑色保护眼睛,亦或者选用户自己喜欢的颜色。
先放具体的实现效果图:
整体思路
- 在 App.js 中,添加一个全局变量 screenProps,把颜色变量放在其中,然后再添加监听,当颜色改变时,触发监听,修改 state 中的颜色值,达到颜色重新渲染。
- 在 router 配置文件中,配置颜色从 screenProps 中获取。
- 换肤页面调用替换颜色方法,触发监听。
核心依赖版本
"react-native": "0.60.5",
"react-navigation": "^3.11.1"
具体实现
一,入口文件中添加全局变量及监听
/**
* Created by supervons 2019/08/02
*
* App 入口文件
* App entry file
*
* https://github.com/supervons/ExploreRN
*
* @format
* @flow
*/
import React, { Component } from 'react';
// 导航路由表
import RootStack from './src/routers/index';
import { View, DeviceEventEmitter } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
color: '#f4511E'
};
}
componentDidMount() {
// 添加全局监听颜色变化
DeviceEventEmitter.addListener('theme_change', params => {
this.setState({
color: params
});
});
}
render(): * {
return (
<View style={{ flex: 1 }}>
<RootStack
screenProps={{
themeColor: this.state.color
}}
/>
</View>
);
}
}
这里讲下,<RootStack/> 是路由配置,在下一步中会修改。
二,修改 router 配置文件
const Tabs = createMaterialTopTabNavigator(
{
MainPage: {
screen: MainPage,
navigationOptions: ({ navigation, screenProps }) => ({
// 涉及到换肤的属性,改为 screenProps.themeColor
...
})
}
})
const Router = createStackNavigator(
{
Login: {
// 登录界面
screen: Login
},
MainPage: {
screen: Tabs
}
},
{
// 定义配置
initialRouteName: 'Login', //设置初始路由为登录界面
headerMode: 'screen',
defaultNavigationOptions: ({ navigation, screenProps }) => ({
// screenProps 即可获取全局变量 themeColor
headerStyle: {
backgroundColor: screenProps.themeColor // <----- 看这里
},
headerTintColor: '#ffffff',
headerTitleStyle: {
fontWeight: 'bold'
}
})
}
);
三,在页面调用方法,触发监听
DeviceEventEmitter.emit('theme_change', 'black');
是的,你没看错,一行代码就触发了换肤。
当然,如果你想保留换肤,还需要存储到后台数据库,然后下次在用户进入 app 从后台拉取配置,就达到了永久换肤了。
项目地址
https://github.com/supervons/ExploreRN
欢迎关注 star ,如果有什么疑惑或者想了解一些高阶技巧,可以关注我的公众号,有问题留言即可: