React Native Context 实现APP的主题开发

重口难调,如果APP的主色调可以自定义,一定程度上就解决了这个问题。

实现思路 

    每个组件之间共享同一个color变量,当用户自定义主题颜色的时候,所有的页面主色调一起发生变化。并且把用户设置的颜色保存到本地存储之中。APP每次启动的时候,从本地存储中获取主题的颜色信息。

效果如下:

React Native Context 实现APP的主题开发

React Native Context 实现APP的主题开发

React Native Context 实现APP的主题开发

js/context/ThemeContext.js

/* eslint-disable prettier/prettier */
import React, {useState,useEffect, createContext} from 'react';
import AsyncStorage from '@react-native-community/async-storage';

export const ThemeContext = createContext();

export const ThemeProvider = props => {
const [backgroundColor,setBackgroundColor] = useState('#1677ff'); //#1677ff
useEffect(()=>{
const queryThemeConfig = async () => {
try {
const cacheBackgroundColor = await AsyncStorage.getItem('@backgroundColor');
if(cacheBackgroundColor!=null){
setBackgroundColor(cacheBackgroundColor);
}
} catch (e) {
// saving error
}
};
queryThemeConfig().then(r => void(0) );
},[]);
return (
<ThemeContext.Provider value={[backgroundColor,setBackgroundColor]}>
{props.children}
</ThemeContext.Provider>
);
};

js/screen/SettingsScreen.js

/* eslint-disable prettier/prettier */
import React, { useState,useContext } from "react";
import { FlatList, SafeAreaView, StatusBar, StyleSheet, Text, TouchableOpacity } from "react-native";
import {ThemeContext} from '../context/ThemeContext';
import AsyncStorage from '@react-native-community/async-storage';
const themeData = [
{
text: 'Default',
color: '#1677ff',
},
{
text: 'Red',
color: '#F44336',
},
{
text: 'Pink',
color: '#E91E63',
},
{
text: 'Purple',
color: '#9C27B0',
},
{
text: 'DeepPurple',
color: '#673AB7',
},
{
text: 'Indigo',
color: '#3F51B5',
},
{
text: 'Blue',
color: '#2196F3',
},
{
text: 'LightBlue',
color: '#03A9F4',
},
{
text: 'Cyan',
color: '#00BCD4',
},
{
text: 'Teal',
color: '#009688',
},
{
text: 'Green',
color: '#4CAF50',
},
{
text: 'LightGreen',
color: '#8BC34A',
},
{
text: 'Lime',
color: '#CDDC39',
},
{
text: 'Yellow',
color: '#FFEB3B',
},
{
text: 'Amber',
color: '#FFC107',
},
{
text: 'Orange',
color: '#FF9800',
},
{
text: 'DeepOrange',
color: '#FF5722',
},
{
text: 'Brown',
color: '#795548',
},
{
text: 'Grey',
color: '#9E9E9E',
},
{
text: 'BlueGrey',
color: '#607D8B',
},
{
text: 'Black',
color: '#000000',
}
];

const Item = ({ item, onPress, style }) => (
<TouchableOpacity onPress={onPress} style={[styles.item, style]}>
<Text style={styles.title}>{item.text}</Text>
</TouchableOpacity>
);

const SettingScreen = () => {
const [backgroundColor,setBackgroundColor] = useContext(ThemeContext);
const saveThemeConfig = async (color) => {
try {
await AsyncStorage.setItem('@backgroundColor', color);
} catch (e) {
// saving error
}
};

const renderItem = ({ item }) => {
const backgroundColor = item.color;
return (
<Item
item={item}
onPress={() => {
setBackgroundColor(item.color);
saveThemeConfig(item.color);
}}
style={{ backgroundColor }}
/>
);
};

return (
<SafeAreaView style={styles.container}>
<FlatList
data={themeData}
renderItem={renderItem}
keyExtractor={(item) => item.text}
/>
</SafeAreaView>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: StatusBar.currentHeight || 0,
},
item: {
padding: 20,
marginVertical: 0,
marginHorizontal: 0,
},
title: {
fontSize: 22,
color: '#ffffff',
},
});

export default SettingScreen;

js/navigation/TabNav.js

/* eslint-disable prettier/prettier */
import React, {useContext} from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {createStackNavigator} from '@react-navigation/stack';
import SchoolScreen from '../screen/SchoolScreen';
import HomeScreen from '../screen/HomeScreen';
import MessageScreen from '../screen/MessageScreen';
import SettingsScreen from '../screen/SettingsScreen';
import AntDesign from 'react-native-vector-icons/AntDesign';
import {ThemeContext} from '../context/ThemeContext';

export default function Navigation({colorScheme}) {
const [backgroundColor, setBackgroundColor] = useContext(ThemeContext);
return (
<Tab.Navigator
screenOptions={({route}) => ({
tabBarIcon: ({focused, color, size}) => {
if (route.name === 'index') {
return <AntDesign name="home" size={size} color={color}/>;
} else if (route.name === 'school') {
return <AntDesign name="cloudo" size={size} color={color}/>;
} else if (route.name === 'message') {
return <AntDesign name="mail" size={size} color={color}/>;
} else if (route.name === 'setting') {
return <AntDesign name="setting" size={size} color={color}/>;
}
},
})}
tabBarOptions={{
activeTintColor: backgroundColor,
}}
>
<Tab.Screen
name="index"
component={HomeNavigator}
options={{title: '首页', headerMode: 'none'}}
/>
<Tab.Screen
name="school"
component={SchoolNavigator}
options={{title: '校园'}}
/>
<Tab.Screen
name="message"
component={MessageNavigator}
options={{title: '消息'}}
/>

<Tab.Screen
name="setting"
component={SettingsScreenNavigator}
options={{title: '设置'}}
/>
</Tab.Navigator>
);
}
const Tab = createBottomTabNavigator();
const TabStack = createStackNavigator();

function HomeNavigator() {
const [backgroundColor, setBackgroundColor] = useContext(ThemeContext);
return (
<TabStack.Navigator>
<TabStack.Screen
name="School"
component={HomeScreen}
options={{
headerTitle: '首页',
headerLeft: null,
headerTitleAlign: 'center',
headerStyle: {
backgroundColor: backgroundColor,
},
headerTitleStyle:{
color: '#fff',
}
}}
/>
</TabStack.Navigator>
);
}

function SchoolNavigator() {
const [backgroundColor, setBackgroundColor] = useContext(ThemeContext);
return (
<TabStack.Navigator>
<TabStack.Screen
name="School"
component={SchoolScreen}
options={{
headerTitle: '校园',
headerLeft: null,
headerTitleAlign: 'center',
headerStyle: {
backgroundColor: backgroundColor,
},
headerTitleStyle:{
color: '#fff',
}
}}
/>
</TabStack.Navigator>
);
}

function MessageNavigator() {
const [backgroundColor, setBackgroundColor] = useContext(ThemeContext);
return (
<TabStack.Navigator>
<TabStack.Screen
name="School"
component={MessageScreen}
options={{
headerTitle: '消息',
headerLeft: null,
headerTitleAlign: 'center',
headerStyle: {
backgroundColor: backgroundColor,
},
headerTitleStyle:{
color: '#fff',
}
}}
/>
</TabStack.Navigator>
);
}

function SettingsScreenNavigator() {
const [backgroundColor, setBackgroundColor] = useContext(ThemeContext);
return (
<TabStack.Navigator>
<TabStack.Screen
name="School"
component={SettingsScreen}
options={{
headerTitle: '主题设置',
headerLeft: null,
headerTitleAlign: 'center',
headerStyle: {
backgroundColor: backgroundColor,
},
headerTitleStyle:{
color: '#fff',
}
}}
/>
</TabStack.Navigator>
);
}

App.js(入口文件)

import React from 'react';
import {
StyleSheet,
SafeAreaView,
StatusBar,
useColorScheme,
} from 'react-native';
import Navigation from './js/navigation';
import {
DarkTheme,
DefaultTheme,
NavigationContainer,
} from '@react-navigation/native';
import {ThemeProvider} from './js/context/ThemeContext';

const App = () => {
const colorScheme = useColorScheme();
return (
<ThemeProvider>
<NavigationContainer
theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
<Navigation />
<StatusBar barStyle={'light-content'} />
</NavigationContainer>
</ThemeProvider>
);
};

export default App;

项目源码下载:

https://download.csdn.net/download/lxyoucan/12910406

 

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

React Native Context 实现APP的主题开发

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » React Native Context 实现APP的主题开发
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏