问题描述
因此,我使用react-native-paper的单选按钮更改主题。但是按钮的选择要花很长时间。我知道切换主题需要一段时间,但我真的不明白为什么按钮不能立即激活。 我的项目在github上:https://github.com/rusagent/testmepls 如果有人可以告诉我我在做什么错,那将很酷。我搜索了互联网,react-native-paper的github问题和stackoverflow,但找不到解决方案...
相关代码如下
app.tsx:
import React from 'react';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { AppLoading } from 'expo';
import { enableScreens } from 'react-native-screens';
import { Provider as PaperProvider } from 'react-native-paper';
import { Main } from './src/main';
import { PreferencesContext } from './src/context/preferencesContext';
import { getTheme,ThemeMode } from './src/theme/themes';
import { AppState,I18nManager } from 'react-native';
import RNRestart from 'react-native-restart';
import { Appearance,AppearanceProvider } from 'react-native-appearance';
import AsyncStorage from '@react-native-community/async-storage';
enableScreens();
export default function App() {
let justloaded = false;
const [themeType,setThemeType] = React.useState(ThemeMode.light);
const [rtl] = React.useState<boolean>(I18nManager.isRTL);
const toggleRTL = React.useCallback(() => {
I18nManager.forceRTL(!rtl);
RNRestart.Restart();
},[rtl]);
const [curTheme,setCurTheme] = React.useState(Appearance.getColorScheme);
const appState = React.useRef(AppState.currentState);
const [appStateVisible,setAppStateVisible] = React.useState(appState.current);
React.useEffect(() => {
AppState.addEventListener("change",_handleAppStateChange);
return () => {
AppState.removeEventListener("change",_handleAppStateChange);
};
},[]);
const _handleAppStateChange = (nextAppState) => {
if(appState.current.match(/inactive|background/)){
setCurTheme(themeType === ThemeMode.light ? 'light' : 'dark');
setData(themeType);
}
if (
appState.current.match(/inactive|background/) &&
nextAppState === "active"
) {
// console.log("App has come to the foreground!");
}
appState.current = nextAppState;
setAppStateVisible(appState.current);
console.log("AppState",appState.current);
};
const setData = async (val) => {
try {
if (justloaded)
return;
else
justloaded = false;
AsyncStorage.setItem('@theme',val);
console.log('set',val);
} catch (e) {
console.log(e);
}
};
const setTheTheme = React.useCallback((type) => {
return setThemeType(type);
},[themeType]);
const preferences = React.useMemo(
() => ({
setTheTheme,toggleRTL,themeType,rtl: (rtl ? 'right' : 'left') as 'right' | 'left',curTheme,}),[rtl,setTheTheme,curTheme],);
React.useEffect(() => {
const sub = Appearance.addchangelistener(onThemeChange);
return () => sub.remove();
},[themeType]);
const onThemeChange = ({}) => {
if (curTheme !== Appearance.getColorScheme())
setCurTheme(Appearance.getColorScheme());
};
function handleFinishLoading(setLoadingComplete) {
setLoadingComplete(true);
}
function handleLoadingError(error) {
console.warn('error',error);
}
const [isLoadingComplete,setLoadingComplete] = React.useState(false);
async function loadResourcesAsync() {
const val = await AsyncStorage.getItem('@theme');
console.log('loaded',val);
justloaded = true;
if (val) {
setTheTheme(val);
setCurTheme(val === ThemeMode.light ? 'light' : 'dark');
}
}
function themeSwitch(param) {
console.log('switch',param);
return getTheme(param);
}
if (!isLoadingComplete) {
return <AppLoading
startAsync={loadResourcesAsync}
onError={handleLoadingError}
onFinish={() => handleFinishLoading(setLoadingComplete)}
/>;
} else {
return (
<AppearanceProvider>
<SafeAreaProvider>
<PreferencesContext.Provider value={preferences}>
<PaperProvider theme={{ ...themeSwitch(themeType) }}>
<Main />
</PaperProvider>
</PreferencesContext.Provider>
</SafeAreaProvider>
</AppearanceProvider>
);
}
}
main.tsx:
import React from 'react';
import { RootNavigator } from './rootNavigator';
export const Main = () => {
return (
<RootNavigator />
);
};
rootnavigator.tsx
import React from 'react';
import {createDrawerNavigator} from '@react-navigation/drawer';
import {NavigationContainer} from '@react-navigation/native';
import {StackNavigator} from './stack';
import {DrawerContent} from './drawerContent';
import {getTheme} from "./theme/themes";
import {PreferencesContext} from "./context/preferencesContext";
import {PrefNavigator} from "./PrefStack";
import {Lednavigator} from "./LedStack";
import { LicNavigator } from "./licstack";
const Drawer = createDrawerNavigator();
export const RootNavigator = () => {
const { themeType } = React.useContext(
PreferencesContext
);
const theme = getTheme(themeType);
return (
<NavigationContainer theme={{...theme}}>
<Drawer.Navigator drawerContent={(props) => <DrawerContent {...props} />}>
<Drawer.Screen name="Home" component={StackNavigator} />
<Drawer.Screen name="Preferences" component={PrefNavigator} />
<Drawer.Screen name="LedList" component={Lednavigator} />
<Drawer.Screen name="Licenses" component={LicNavigator} />
</Drawer.Navigator>
</NavigationContainer>
);
};
prefstack.tsx:
import {createStackNavigator} from "@react-navigation/stack";
import {Appbar,useTheme} from "react-native-paper";
import {TouchableOpacity} from "react-native";
import {DrawerNavigationProp} from "@react-navigation/drawer";
import {Preferences} from "./preferences";
import React from "react";
import {PreferencesContext} from "./context/preferencesContext";
import {getTheme} from "./theme/themes";
import { Ionicons } from './icons';
const Pref = createStackNavigator();
export const PrefNavigator = () => {
const { themeType } = React.useContext(
PreferencesContext
);
const theme = getTheme(themeType);
return (
<Pref.Navigator
initialRouteName="Preferences"
headerMode="screen"
screenoptions={{
header: ({ navigation }) => {
return (
<Appbar.Header
theme={{ colors: { primary: theme.colors.surface } }}
>
<TouchableOpacity
style={{ marginLeft: 10 }}
onPress={() => {
((navigation as any) as DrawerNavigationProp<{}>).openDrawer();
}}
>
<Ionicons
name="ios-menu"
size={40}
color={theme.colors.primary}
/>
</TouchableOpacity>
<Appbar.Content
title="Options"
titleStyle={{
fontSize: 18,fontWeight: 'bold',color: theme.colors.primary,}}
/>
</Appbar.Header>
);
},}}
>
<Pref.Screen
name="Preferences"
component={Preferences}
options={{headerTitle: "Settings"}}
/>
</Pref.Navigator>
);
};
preferences.tsx:
import React from "react";
import { StyleSheet,View } from "react-native";
import { RadioButton,Switch,Text,TouchableRipple } from "react-native-paper";
import { PreferencesContext } from "./context/preferencesContext";
import { getTheme,ThemeMode } from "./theme/themes";
export const Preferences = () => {
const { rtl,setTheTheme } = React.useContext(
PreferencesContext
);
const theme = getTheme(themeType);
return (
<View style={{ backgroundColor: theme.colors.surface,height: '100%' }}>
<View>
<Text>Light</Text>
<RadioButton
value={ThemeMode.light}
status={ themeType === ThemeMode.light ? 'checked' : 'unchecked'}
onPress={() => setTheTheme(ThemeMode.light)}
/>
</View>
<View>
<Text>Dark</Text>
<RadioButton
value={ThemeMode.dark}
status={themeType === ThemeMode.dark ? 'checked' : 'unchecked'}
onPress={() => setTheTheme(ThemeMode.dark)}
/>
</View>
<View>
<Text>System</Text>
<RadioButton
value={ThemeMode.system}
status={themeType === ThemeMode.system ? 'checked' : 'unchecked'}
onPress={() => setTheTheme(ThemeMode.system)}
/>
</View>
<TouchableRipple onPress={toggleRTL}>
<View style={styles.preference}>
<Text>RTL</Text>
<View pointerEvents="none">
<Switch value={rtl === 'right'} />
</View>
</View>
</TouchableRipple>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,alignItems: 'center',justifyContent: 'center',},preference: {
flexDirection: 'row',justifyContent: 'space-between',paddingVertical: 12,paddingHorizontal: 16,});
themes.tsx:
import {
DarkTheme as NavigationDarkTheme,DefaultTheme as NavigationDefaultTheme,} from '@react-navigation/native';
import {
DarkTheme as PaperDarkTheme,DefaultTheme as PaperDefaultTheme,} from 'react-native-paper';
import merge from 'deepmerge';
import { Appearance } from 'react-native-appearance';
const CombinedDefaultTheme = merge(PaperDefaultTheme,NavigationDefaultTheme);
const CombinedDarkTheme = merge(PaperDarkTheme,NavigationDarkTheme);
export let currentTheme = CombinedDefaultTheme;
export const setDark = () => {
currentTheme = {
...CombinedDarkTheme,colors: { ...CombinedDarkTheme.colors,primary: '#1ba1f2' },};
};
export const setLight = () => {
currentTheme = {
...CombinedDefaultTheme,colors: { ...CombinedDefaultTheme.colors,};
};
export const getTheme = (mode: ThemeMode) => {
switch (mode) {
case ThemeMode.dark: {
setDark();
break;
}
case ThemeMode.light: {
setLight();
break;
}
case ThemeMode.system: {
Appearance.getColorScheme() === 'dark' ? setDark() : setLight();
return currentTheme;
}
case ThemeMode.current:
return currentTheme;
}
return currentTheme;
};
export enum ThemeMode {
dark = 'dark',light = 'light',system = 'system',current = 'current'
}
我认为应该足够了...:/
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)