Pracuję nad tutorialem do nawigacji w React Native. Dowiedziałem się, że cały układ zaczyna się ładować od góry ekranu, a nie od dołu paska stanu. Powoduje to, że większość układów nakłada się na pasek stanu. Mogę to naprawić, dodając wypełnienie do widoku podczas ich ładowania. Czy to jest właściwy sposób? Nie sądzę, aby ręczne dodawanie dopełnienia było rzeczywistym sposobem rozwiązania tego problemu. Czy jest bardziej elegancki sposób, aby to naprawić?
import React, { Component } from 'react';
import { View, Text, Navigator } from 'react-native';
export default class MyScene extends Component {
static get defaultProps() {
return {
title : 'MyScene'
};
}
render() {
return (
<View style={{padding: 20}}> //padding to prevent overlap
<Text>Hi! My name is {this.props.title}.</Text>
</View>
)
}
}
Poniżej przedstawiono zrzuty ekranu przed i po dodaniu wypełnienia.
ios
react-native
Klif
źródło
źródło
Odpowiedzi:
Jest bardzo prosty sposób, aby to naprawić. Zrób komponent.
Możesz utworzyć komponent StatusBar i wywołać go najpierw po pierwszym opakowaniu widoku w komponentach nadrzędnych.
Oto kod tego, którego używam:
'use strict' import React, {Component} from 'react'; import {View, Text, StyleSheet, Platform} from 'react-native'; class StatusBarBackground extends Component{ render(){ return( <View style={[styles.statusBarBackground, this.props.style || {}]}> //This part is just so you can change the color of the status bar from the parents by passing it as a prop </View> ); } } const styles = StyleSheet.create({ statusBarBackground: { height: (Platform.OS === 'ios') ? 18 : 0, //this is just to test if the platform is iOS to give it a height of 18, else, no height (Android apps have their own status bar) backgroundColor: "white", } }) module.exports= StatusBarBackground
Po wykonaniu tej czynności i wyeksportowaniu go do głównego komponentu, nazwij to w ten sposób:
import StatusBarBackground from './YourPath/StatusBarBackground' export default class MyScene extends Component { render(){ return( <View> <StatusBarBackground style={{backgroundColor:'midnightblue'}}/> </View> ) } }
źródło
MidnightBlue
jest nieważny, opowiedziana przez React Native: Ostrzeżenie: Nie Typ prop: Nieprawidłowy propbackgroundColor
dostarczonemidnightblue
.height: (Platform.OS === 'ios') ? 20 : StatusBar.currentHeight,
zamiast tego? 20 : 0,
uzyskasz ten sam wynik na Androidzie.Teraz możesz użyć tego,
SafeAreaView
co jest zawarte w React Navigation:<SafeAreaView> ... your content ... </SafeAreaView>
źródło
react-navigation
teraz domyślnie zawarty w programie .Wypróbowałem prostszy sposób.
Możemy uzyskać wysokość paska stanu na Androidzie i użyć razem z nim SafeAreaView, aby kod działał na obu platformach.
import { SafeAreaView, StatusBar, Platform } from 'react-native';
Jeśli się wylogujemy
Platform.OS
iStatusBar.currentHeight
otrzymamy logi,console.log('Height on: ', Platform.OS, StatusBar.currentHeight);
Wysokość na: Android 24 i Wysokość na: Android 24
Możemy teraz opcjonalnie dodać margines / dopełnienie do naszego widoku kontenera za pomocą
paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0
Ostateczny kod w App.js znajduje się poniżej:
export default class App extends React.Component { render() { return ( <SafeAreaView style={{ flex: 1, backgroundColor: "#fff" }}> <View style={styles.container}> <Text>Hello World</Text> </View> </SafeAreaView> ); } } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff", paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0 } });
źródło
Rozwiązanie @philipheinser rzeczywiście działa.
Spodziewałbym się jednak, że komponent StatusBar React Native zajmie się tym za nas.
Niestety tak nie jest, ale możemy to dość łatwo wyodrębnić, tworząc wokół niego własny komponent:
./StatusBar.js
import React from 'react'; import { View, StatusBar, Platform } from 'react-native'; // here, we add the spacing for iOS // and pass the rest of the props to React Native's StatusBar export default function (props) { const height = (Platform.OS === 'ios') ? 20 : 0; const { backgroundColor } = props; return ( <View style={{ height, backgroundColor }}> <StatusBar { ...props } /> </View> ); }
./index.js
Przed: Po:import React from 'react'; import { View } from 'react-native'; import StatusBar from './StatusBar'; export default function App () { return ( <View> <StatusBar backgroundColor="#2EBD6B" barStyle="light-content" /> { /* rest of our app */ } </View> ) }
źródło
Dokumenty
react-navigation
mają na to świetne rozwiązanie. Po pierwsze, zaleca się nie używaćSafeAreaView
dołączonej React Native ponieważ:Zamiast tego zalecają reakcję-natywny-bezpieczny-kontekst-obszaru - z którym wyglądałoby to tak:
import React, { Component } from 'react'; import { View, Text, Navigator } from 'react-native'; import { useSafeArea } from 'react-native-safe-area-context'; export default function MyScene({title = 'MyScene'}) { const insets = useSafeArea(); return ( <View style={{paddingTop: insets.top}}> <Text>Hi! My name is {title}.</Text> </View> ) }
Chciałbym zauważyć, że prawdopodobnie lepszym pomysłem jest skorzystanie z
SafeAreaView
tego, co oferuje ta biblioteka, ponieważ telefony w dzisiejszych czasach mogą mieć również elementy na dole, które mogą nakładać się na elementy interfejsu użytkownika. Wszystko zależy oczywiście od Twojej aplikacji. (Więcej informacji na ten temat można znaleźć wreact-navigation
dokumentach, do których utworzyłem łącze na początku).źródło
Oto sposób, który działa na iOS :
<View style={{height: 20, backgroundColor: 'white', marginTop: -20, zIndex: 2}}> <StatusBar barStyle="dark-content"/></View>
źródło
Możesz sobie z tym poradzić, dodając wypełnienie do komponentu paska nawigacyjnego lub po prostu reklamując widok, który ma taką samą wysokość jak pasek stanu u góry drzewa widoku, z kolorem tła, tak jak robi to aplikacja na Facebooku.
źródło
Just Simple User React natywny Default StatusBar, aby osiągnąć tę funkcjonalność.
<View style={styles.container}> <StatusBar backgroundColor={Color.TRANSPARENT} translucent={true} /> <MapView provider={PROVIDER_GOOGLE} // remove if not using Google Maps style={styles.map} region={{ latitude: 37.78825, longitude: -122.4324, latitudeDelta: 0.015, longitudeDelta: 0.0121, }} /> </View>
źródło