【问题标题】:Extend colors in React Navigation default themes在 React Navigation 默认主题中扩展颜色
【发布时间】:2021-06-25 00:30:47
【问题描述】:

我在我的应用程序中使用 React Navigation Default 和 Dark 主题。用户可以通过切换按钮更改主题,一切正常。

现在我想为默认主题和深色主题添加其他颜色。 所以默认情况下他们有这样的东西:

Object {
  "background": "rgb(1, 1, 1)",
  "border": "rgb(39, 39, 41)",
  "card": "rgb(18, 18, 18)",
  "notification": "rgb(255, 69, 58)",
  "primary": "rgb(10, 132, 255)",
  "text": "rgb(229, 229, 231)",
}

我想做的是附加如下内容:

"commentText": "rgb(200, 200, 100)"

我目前是这样调用主题的:

import { useTheme } from "@react-navigation/native";
const { colors } = useTheme();
  const styles = StyleSheet.create({
    text: {
      fontSize: 16,
      color: colors.text,
    },
  });

// in my component ...

<Text style={styles.text}>Date format</Text>

最好的方法是什么?我是否需要完全定义自己的自定义主题,包括原始颜色和我的颜色?有什么方法可以简单地附加到原始的?

更新:

我部分关注了this guide,还决定创建自己的主题并添加更多条目(在这篇文章中不可见)。 现在我当前的挑战是直接在定义我的样式的文件中移动颜色定义(例如typography.js)。如果我使用定义的颜色(例如border: "#d8d8d8"),它可以正常工作,但我希望它能够选择主题(例如color: colors.text)。

问题是 useTheme() 只能在 React 函数组件或自定义 React Hook 函数中调用。 例如,我如何在typography.js 中使用它?

下面提供的代码,请注意 cmets。

Home.js

import { useTheme } from "@react-navigation/native";
import React, { useContext, useEffect, useState } from "react";
import {
  Dimensions,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from "react-native";

import { borders, buttons, layout, typography } from "../styles";

const Home = ({ navigation }) => {

  const { colors } = useTheme();

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      backgroundColor: colors.background  // Works fine
    },
    buttonText: {
      ...typography.buttonText,
      color: colors.text,      // I would like to move this to typography.js
    }
  });

  return (
    <>
      <View style={styles.container}>
        <Text style={styles.buttonText}>blabla</Text>
        // More code here....
      </View>
    </>
  );
};

export default Home;

./styles/index.js

import * as themes from "./themes";
import * as typography from "./typography";

export {
  themes,
  typography
};

./styles/themes.js

export const MyDefaultTheme = {
  dark: false,
  colors: {
    background: "#f2f2f2",
    border: "#d8d8d8", 
    card: "#ffffff", 
    notification: "#ff3b30",
    primary: "#007aff", 
    text: "#1c1c1e", 
  },
};

export const MyDarkTheme = {
  dark: true,
  colors: {
    background: "#010101", 
    border: "#272729", 
    card: "#121212",
    notification: "#ff453a", 
    primary: "#0a84ff", 
    text: "#e5e5e7", 
  },
};

./styles/typography.js

import { useTheme } from "@react-navigation/native"; // // This isn't working
const { colors } = useTheme(); // This isn't working

export const textHeader = {
  fontWeight: "bold",
  fontSize: 30,
  textAlign: "center",
  marginBottom: 20,
};

export const buttonText = {
  fontSize: 14,
  textAlign: "center",
  color: colors.text  // This is not working 
};

【问题讨论】:

    标签: reactjs react-native themes react-navigation


    【解决方案1】:

    您正在寻找的是Appearance API。限制是您被鼓励使用内联样式,因为主题可能会改变,例如从白天切换到黑夜。

    在您的示例代码中,您在组件外部调用 useTheme(),因此它不起作用。您对内联颜色样式的原始解决方案似乎正是 React Native 团队所推荐的。

    【讨论】:

      【解决方案2】:

      您需要在 Redux 中存储一个值,并基于此值,您可以通过在每个组件中获取此值来更改每个组件的颜色。
      只需在 App.js 中调度操作并根据存储在 redux 中的值应用自定义颜色。

          useEffect(() => {
          subscription = Appearance.addChangeListener(({ colorScheme }) => {
              if (colorScheme === 'light') {
                  dispatch(setMode(false));
              } else {
                  dispatch(setMode(true));
              }
          });
          return () => subscription && subscription.remove();
      }, []);
      

      【讨论】:

      • 我对 Redux 不是很熟悉,目前还没有使用它。我已经读过它,但这真的是要走的路吗?对于我正在尝试做的事情来说,这似乎是一种矫枉过正。
      • 这是一个相当大的假设,即 Redux 在代码库中。
      猜你喜欢
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-01
      • 2018-04-10
      • 1970-01-01
      • 2017-04-13
      • 2017-12-09
      相关资源
      最近更新 更多