【问题标题】:React-navigation switch theme toggleReact-navigation 切换主题切换
【发布时间】:2021-09-10 15:08:27
【问题描述】:

我已经通过 react-navigation 在我的应用中实现了主题支持,如下所示。 我正在使用系统主题设置,我的应用程序遵循此规则 这很好用,但我的待办事项清单上还剩下一件事, 在我的应用程序中切换浅色/深色主题的选项, 保留此选择,并将其存储到用户默认值或类似的东西中..

我关注了官方文档 (https://reactnavigation.org/docs/themes/) 但他们没有提到如何手动切换主题。 在我的测试中,我总是收到一条消息,主题道具是只读的,不能手动更改。 那么该怎么做呢? 任何帮助将不胜感激;)

App.js

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { AppearanceProvider, useColorScheme, useTheme } from 'react-native-appearance';

const Stack = createStackNavigator();

// ------------------App-----------------------------
export default function App() {

    const scheme = useColorScheme();

    const MyDarkTheme = {
    dark: true,
    ...},
    const LightTheme = {
    dark: false,
    ...}
    
    return (
      <AppearanceProvider>
        <NavigationContainer theme={scheme === "dark" ? MyDarkTheme : LightTheme}>
          <Stack.Navigator>
          <Stack.Screen>
            name="home"
          ...
          <Stack.Screen
            name="Settings"
            component={Settings}
            />
          </Stack.Navigator>
        </NavigationContainer>
      </AppearanceProvider>
    );
  }

在我的组件中:

import React, { useState, useEffect} from 'react';
import { Card } from 'react-native-elements';
import { useTheme} from '@react-navigation/native';

function CardOne(props) {

    const { colors } = useTheme(); // works
    const theme = useTheme();

return (
        <Card containerStyle={{backgroundColor: colors.cardBackgroundColor, borderColor: colors.borderColor, borderWidth: 2, borderRadius: 5}}>
        ...
        </Card>
        );
}  
export default CardOne;

我真的有人可以帮助我;)

【问题讨论】:

  • 您是否使用上下文或任何类型的状态管理来存储当前主题?
  • 还没有,我不知道该怎么做..我只是将我的类转换为函数,我记得我以前使用过“上下文”,因为我不得不并且不能使用“ useTheme" 钩子,..我真的很好奇你的方法(y)

标签: javascript reactjs react-native react-navigation-v5


【解决方案1】:

您可以使用上下文并执行以下操作,基本上在 App.js 中保持主题状态并通过上下文更新值。

export const ThemeContext = React.createContext();

export default function App() {
  const [theme, setTheme] = useState('Light');

  const themeData = { theme, setTheme };
  return (
    <ThemeContext.Provider value={themeData}>
      <NavigationContainer theme={theme == 'Light' ? DefaultTheme : DarkTheme}>
        <Drawer.Navigator initialRouteName="Root">
          <Drawer.Screen name="Home" component={HomeScreen} />
          <Drawer.Screen name="Root" component={Root} />
        </Drawer.Navigator>
      </NavigationContainer>
    </ThemeContext.Provider>
  );
}

您可以从如下屏幕切换主题

function ProfileScreen({ navigation }) {
  const { setTheme, theme } = React.useContext(ThemeContext);
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Profile Screen</Text>
      <Button
        title="Switch Theme"
        onPress={() => setTheme(theme === 'Light' ? 'Dark' : 'Light')}
      />
    </View>
  );
}

示例代码 https://snack.expo.io/@guruparan/5b84d0

【讨论】:

  • 这是一种很棒的方法,我开始理解了,但是当我尝试使用 app.js 文件中的上下文时,我被困在“Context._context”评估失败的设置页面上。 - '未定义不是一个对象(评估'Context._context)
  • 我找到了解决方案 :) 我将 ThemeContext 创建移到了它自己的文件中,并将这个文件导入到组件文件中...就像一个魅力 - 非常感谢!
猜你喜欢
  • 2021-04-26
  • 2020-09-02
  • 2022-09-30
  • 2020-12-09
  • 2020-06-07
  • 2022-01-09
  • 1970-01-01
  • 2021-08-12
  • 2018-01-04
相关资源
最近更新 更多