Dark Theme com React Navigation + Typescript + React Native Paper
27442 단어 reactnativetypescript
Você também pode ver esse tutorial em video e o repositório no Github .
Criando projeto React Native com Typescript
React Native는 Typescript와 함께 프로젝트를 진행하고 있으며, 가장 먼저 시작하고 있습니다.
npx react-native init NavigationTypescriptPaper --template react-native-template-typescript
Referência da documentação
Instalando 반응 탐색
Para instalar o React Navigation precisamos instalar os seguintes pacotes
yarn add @react-navigation/native react-native-screens react-native-safe-area-context
이 종속성은 사용자가 사용할 수 있는 정보를 탐색할 때 사용하지 않는 경우에만 사용할 수 있습니다. Para usarmos um Stack, precisamos instalar
yarn add @react-navigation/stack
Caso vocês esteja usando Mac, rode o comando
npx pod-install ios
E para Android, você precisa editar o arquivo
MainActivity.java
que fica em android/app/src/main/java/<nome do projeto>/MainActivity.java
import android.os.Bundle;
// ...
public class MainActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
}
// ...
}
Referência da documentação
Instalando 리액트 네이티브 페이퍼
Para instalar o React Native Paper precisamos instalar os seguintes pacotes 설치
yarn add react-native-paper react-native-vector-icons
Referência da documentação
Caso você esteja usando Mac, edite sei
PodFile
e adicione o seguinte códigopod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
Android 사용자는 문서가 필요하지 않습니다
android/app/build.gradle
.apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
Referência da documentação
Criando 또는 ThemeContext 및 ThemeContextProvider
Primeiro iremos importar os temas tanto do React Navigation como do React Native Paper
import {
DarkTheme as NavigationDarkTheme,
DefaultTheme as NavigationDefaultTheme,
NavigationContainer,
} from '@react-navigation/native';
import {
DarkTheme as PaperDarkTheme,
DefaultTheme as PaperDefaultTheme,
Provider as PaperProvider,
} from 'react-native-paper';
E assim iremos dar um merge nos temas, criando um tema
light
com a junção dos dois temas default e um temas dark
com a junção dos dois temas dark.const lightTheme = {
...NavigationDefaultTheme,
...PaperDefaultTheme,
colors: {
...NavigationDefaultTheme.colors,
...PaperDefaultTheme.colors,
},
};
const darkTheme = {
...NavigationDarkTheme,
...PaperDarkTheme,
colors: {
...NavigationDarkTheme.colors,
...PaperDarkTheme.colors,
},
};
Assim teremos os dois temas definidos com os valores default dos dois pacotes e poderemos adicionar nossas próprias cores caso desejado.
Em seguida já podemos definir 2 tipos que usaremos sobre o nosso tema. O Primeiro é criar um tipo que definira o nosso tema, utilizando o
typeof
do lightTheme
, assim caso adicionemos alguma configuração a mais no nosso tema, ele é refletido para o tipo.export type Theme = typeof lightTheme;
E também definiremos os tipos de temas que teremos, que no caso será
light
및 dark
.export type ThemeType = 'dark' | 'light';
Assim já podemos definir quais dados teremos nosso context가 없습니다. Passaremos o tema atual, assim como seu tipo, um booleano indicando se o tema é dark, para facilitar a comparação na hora de utilizar, uma função para alternar o valor do tema e outra para atualizar diretamente o tema caso seja necessário.
export interface ThemeContextValue {
theme: Theme;
themeType: ThemeType;
isDarkTheme: boolean;
toggleThemeType: () => void;
setThemeType: React.Dispatch<React.SetStateAction<ThemeType>>;
}
E assim utilizaremos
React.createContext
para criar o contexto e passaremos valores default para cara propriedade.export const ThemeContext = React.createContext<ThemeContextValue>({
theme: lightTheme,
themeType: 'light',
isDarkTheme: false,
setThemeType: () => {},
toggleThemeType: () => {},
});
Como vamos utilizar hooks, já podemos criar o nosso próprio hook que chamaremos de
useTheme
, simplesmente para facilitar a utilização desse contexto.export const useTheme = () => useContext(ThemeContext);
컨텍스트를 구현하는 데 사용할 수 있는 항목은 구성 요소에 대한 정의
ThemeContextProvider
이며 소품과 관련된 인터페이스입니다.export interface ThemeContextProviderProps {
children: React.ReactNode;
}
export const ThemeContextProvider = ({children}: ThemeContextProviderProps) => {
// ...
}
Dentro dele utilizaremos o
useColorScheme
para saber se o celular está no modo normal ou dark mode e passaremos esse valor para um useState
onde armazenaremos o tipo do tema.export const ThemeContextProvider = ({children}: ThemeContextProviderProps) => {
const colorScheme = useColorScheme();
const [themeType, setThemeType] = useState<ThemeType>(colorScheme || 'light');
// ...
}
Criaremos uma simples função para alternar or tipo do tema.
export const ThemeContextProvider = ({children}: ThemeContextProviderProps) => {
// ...
const toggleThemeType = useCallback(() => {
setThemeType(prev => (prev === 'dark' ? 'light' : 'dark'));
}, []);
// ...
}
E também definiremos
isDarkTheme
e o tema em si a ser utilizadoexport const ThemeContextProvider = ({children}: ThemeContextProviderProps) => {
// ...
const isDarkTheme = useMemo(() => themeType === 'dark', [themeType]);
const theme = useMemo(
() => (isDarkTheme ? darkTheme : lightTheme),
[isDarkTheme],
);
// ...
}
Agora que temos todos os valores do nosso context definidos, podemos renderizar o
NavigationContainer
eo PaperProvider
para passar o tema e também nosso provider com os valores do context.O componente complete ficaria da seguinte forma
export const ThemeContextProvider = ({children}: ThemeContextProviderProps) => {
const colorScheme = useColorScheme();
const [themeType, setThemeType] = useState<ThemeType>(colorScheme || 'light');
const toggleThemeType = useCallback(() => {
setThemeType(prev => (prev === 'dark' ? 'light' : 'dark'));
}, []);
const isDarkTheme = useMemo(() => themeType === 'dark', [themeType]);
const theme = useMemo(
() => (isDarkTheme ? darkTheme : lightTheme),
[isDarkTheme],
);
return (
<NavigationContainer theme={theme}>
<PaperProvider theme={theme}>
<ThemeContext.Provider
value={{
theme,
themeType,
isDarkTheme,
setThemeType,
toggleThemeType,
}}>
{children}
</ThemeContext.Provider>
</PaperProvider>
</NavigationContainer>
);
};
컨텍스트 및 테마 변경 활용
Em nosso
App.tsx
iremos renderizar o ThemeContextProvider
e dentro dele utilizaremos um stack para a navegação através do createStackNavigator
. Dentro desse stack teremos uma tela apenas para demonstrar que o tema está funcionando.const TestScreen = () => {
// ...
};
const Stack = createStackNavigator();
const App = () => {
return (
<ThemeContextProvider>
<Stack.Navigator>
<Stack.Screen name="Test" component={TestScreen} />
</Stack.Navigator>
</ThemeContextProvider>
);
};
Dentro da nossa tela de teste, podemos utilizar o custom hook que criamos
useTheme
para pegar os valores do context e utilizarmos da forma que preferirmos.const TestScreen = () => {
const {toggleThemeType, themeType, isDarkTheme, theme} = useTheme();
return (
<View>
<Button mode="contained" onPress={toggleThemeType}>
Toggle Theme
</Button>
<Headline>{themeType}</Headline>
<Headline>isDarkTheme: {`${isDarkTheme}`}</Headline>
<Headline>Primary: {theme.colors.primary}</Headline>
</View>
);
};
Assim, apertando o botão podemos ver que o tema muda.
Podemos analisar também que se você colocar o celular no modo escuro, o aplicativo já inicia o tema como
dark
.
Reference
이 문제에 관하여(Dark Theme com React Navigation + Typescript + React Native Paper), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/magoacademico/dark-theme-com-react-navigation-typescript-react-native-paper-55ob텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)