react-native-paper单选按钮需要很长时间才能更改

问题描述

因此,我使用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 (将#修改为@)