React Native에서 테마 구성 요소 빌드

22390 단어 typescriptreactnative
사용자 지정 구성 요소를 활용하는 한 다중 테마 앱을 구축하는 것이 복잡할 필요는 없습니다. 이 튜토리얼에서는 사용자가 선호하는 색 구성표를 기반으로 올바른 색상을 사용하도록 자동으로 테마가 지정되는 핵심 React Native 구성 요소 버전을 만드는 방법을 다룹니다.

아래 StopWatch 화면의 코드를 살펴보십시오. 여러 테마를 지원하는 데 고유한 것은 없지만 우리가 만들 사용자 지정 구성 요소 덕분에 여러 테마를 완벽하게 지원합니다.

// screens/StopWatch.tsx

import { StyleSheet } from "react-native"

import { Text, View, StatusBar, SafeAreaView } from "components/themed"
import { CircleButton } from "components/buttons"
import { useStopWatch } from "hooks/useStopWatch"
import { LapList } from "components/lists"

const StopWatch = () => {
  const {
    time,
    isRunning,
    start,
    stop,
    reset,
    lap,
    laps,
    currentLapTime,
    hasStarted,
    slowestLapTime,
    fastestLapTime,
  } = useStopWatch()

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <StatusBar />
      <View style={styles.container}>
        <Text style={styles.timeText}>{time}</Text>

        <View style={styles.row}>
          <CircleButton
            onPress={() => {
              isRunning ? lap() : reset()
            }}
          >
            {isRunning ? "Lap" : "Reset"}
          </CircleButton>
          <CircleButton
            onPress={() => {
              isRunning ? stop() : start()
            }}
            color={isRunning ? "red" : "green"}
          >
            {isRunning ? "Stop" : "Start"}
          </CircleButton>
        </View>

        <LapList
          hasStarted={hasStarted}
          currentLapTime={currentLapTime}
          laps={laps}
          fastestLapTime={fastestLapTime}
          slowestLapTime={slowestLapTime}
        />
      </View>
    </SafeAreaView>
  )
}

const styles = StyleSheet.create({
  container: { flex: 1, alignItems: "center" },
  timeText: {
    fontSize: 60,
    fontWeight: "300",
    marginTop: 100,
    fontVariant: ["tabular-nums"], // fixed width character
  },
  row: {
    flexDirection: "row",
    width: "100%",
    justifyContent: "space-between",
    paddingHorizontal: 20,
    marginTop: 100,
  },
})

export default StopWatch




useThemeColors 후크



테마 구성 요소의 핵심에는 useThemeColors 후크가 있습니다. 이 후크는 테마 기반 논리를 위해 무거운 작업을 수행합니다.

우리는 a recent tutorial에 이 후크 버전을 만들었습니다. 그것을 구현하는 방법과 그 뒤에 있는 "이유"를 더 잘 이해하기 위해 그것을 읽는 것이 좋습니다.

이 후크에서 우리는 두 가지 데이터 조각이 있는 객체를 반환합니다.
  • 현재 활성 테마의 색상입니다. 이것은 "light"와 "dark"사이에서 표준화됩니다. 다른 테마로 확장할 수도 있습니다.
  • isDarkStatusBar와 같은 사물의 색상을 결정하는 데 사용됩니다. 실제 텍스트 색상을 변경할 수는 없지만 텍스트가 밝거나 어두워야 하는지 결정할 수 있습니다.

  • // hooks/useThemeColors.tsx
    
    import Colors from "constants/Colors"
    import { useColorScheme } from "hooks/useColorScheme"
    
    export function useThemeColors() {
      const theme = useColorScheme()
    
      return {
        isDark: theme === "dark",
        colors: Colors[theme],
      }
    }
    


    보기 구성 요소



    사용자 지정View 구성 요소의 목표는 일반 구성 요소View처럼 작동하는 빌딩 블록 역할을 하는 것입니다. 배경색을 설정한 다음 사용자 정의 소품을 기본View으로 전달하기만 하면 됩니다.

    이렇게 하면 기본 배경색을 재정의하는 것을 포함하여 일반View처럼 사용자 정의View를 사용할 수 있습니다. SafeAreaView도 마찬가지입니다.

    // components/themed/View.tsx
    
    import { View as DefaultView, ViewProps } from "react-native"
    import { SafeAreaView as DefaultSafeAreaView } from "react-native-safe-area-context"
    
    import { useThemeColors } from "hooks/useThemeColors"
    
    export function View(props: ViewProps) {
      const { style, ...otherProps } = props
      const { colors } = useThemeColors()
    
      return (
        <DefaultView
          style={[{ backgroundColor: colors.background }, style]}
          {...otherProps}
        />
      )
    }
    
    export const SafeAreaView = (props: ViewProps) => {
      const { style, ...otherProps } = props
      const { colors } = useThemeColors()
    
      return (
        <DefaultSafeAreaView
          style={[{ backgroundColor: colors.background }, style]}
          {...otherProps}
        />
      )
    }
    


    Learn how to set up path alias' like you see used throughout this post

    텍스트 구성 요소


    View 구성 요소와 마찬가지로 모든 Text 구성 요소는 테마를 기반으로 텍스트 색상을 설정합니다. 다른 옵션은 기본 글꼴 패밀리를 설정하고 다른 텍스트 유형("제목", "자막"등)을 추가하는 것입니다. 여러 테마를 지원하지 않더라도 자신만의 구성 요소Text를 만드는 것이 좋은 방법이므로 글꼴 모음이 변경될 때 앱 전체에서 스타일을 업데이트할 필요가 없습니다.

    // components/themed/Text.tsx
    
    import { Text as DefaultText, TextProps } from "react-native"
    
    import { useThemeColors } from "hooks/useThemeColors"
    
    export const Text = (props: TextProps) => {
      const { style, ...otherProps } = props
      const { colors } = useThemeColors()
    
      return <DefaultText style={[{ color: colors.text }, style]} {...otherProps} />
    }
    


    StatusBar 구성 요소



    이것은 일부만 사용자 정의할 수 있기 때문에 고유합니다. 따라서 isDark 데이터를 사용하여 밝은 텍스트 또는 어두운 텍스트를 사용해야 하는지 여부를 결정합니다. Android에서 StatusBar의 배경색을 설정할 수도 있습니다.

    이 접근 방식을 사용할 때의 이점은 더 많은 테마를 추가하기로 선택한 경우(the example repo this tutorial is based on has 와 같이) 테마가 밝은지 어두운지 한 곳에서 정의할 수 있다는 것입니다.

    // components/themed/StatusBar.tsx
    
    import { StatusBar as DefaultStatusBar, StatusBarProps } from "react-native"
    
    import { useThemeColors } from "hooks/useThemeColors"
    
    export const StatusBar = (props: StatusBarProps) => {
      const { isDark, colors } = useThemeColors()
    
      const barStyle = isDark ? "light-content" : "dark-content"
    
      return (
        <DefaultStatusBar
          barStyle={barStyle}
          backgroundColor={colors.background}
          {...props}
        />
      )
    }
    


    도전



    테마를 지정할 수 있는 더 많은 기본 UI 요소가 있습니다. 여기서 논의된 내용으로 어떻게 하시겠습니까?
  • 버튼이 다릅니다. 그들은 color의 소품을 가지고 있지만 명시된 색상은 각 테마에 대해 동일하지 않을 수 있습니다.
  • React Navigation의 탭 모음입니다. 배경 색상과 아이콘은 테마에 따라 사용자 정의됩니다.

  • answers exist in the repo 하지만 내가 한 방법을 찾기 위해 저장소를 파헤치기 전에 어떻게 할 것인지 생각해 보시기 바랍니다.

    좋은 웹페이지 즐겨찾기