Estoy desarrollando una aplicación React Native para implementarla como una aplicación nativa en iOS y Android (y Windows, si es posible).
El problema es que queremos que el diseño sea diferente según las dimensiones de la pantalla y su orientación.
Hice algunas funciones que devuelven el objeto de estilos y se llaman en la función de representación de cada componente, por lo que puedo aplicar diferentes estilos al inicio de la aplicación, pero si la orientación (o el tamaño de la pantalla) cambia una vez que la aplicación se ha inicializado, no se recalculan ni se vuelven a aplicar.
Agregué oyentes a la parte superior renderizada para que actualice su estado en el cambio de orientación (y fuerza un renderizado para el resto de la aplicación), pero los subcomponentes no se vuelven a renderizar (porque, de hecho, no se han cambiado ).
Entonces, mi pregunta es: ¿cómo puedo hacer para tener estilos que pueden ser completamente diferentes según el tamaño y la orientación de la pantalla, al igual que con CSS Media Queries (que se procesan sobre la marcha)?
Ya probé el módulo react-native-responsive sin suerte.
¡Gracias!
Si usa ganchos. Puede consultar esta solución: https://stackoverflow.com/a/61838183/5648340
La orientación de las aplicaciones de vertical a horizontal y viceversa es una tarea que parece fácil pero que puede ser complicada en reaccionar de forma nativa cuando se debe cambiar la vista cuando cambia la orientación. En otras palabras, tener vistas diferentes definidas para las dos orientaciones se puede lograr considerando estos dos pasos.
Importar dimensiones desde React Native
import { Dimensions } from 'react-native';Para identificar la orientación actual y representar la vista en consecuencia
/** * Returns true if the screen is in portrait mode */ const isPortrait = () => { const dim = Dimensions.get('screen'); return dim.height >= dim.width; }; /** * Returns true of the screen is in landscape mode */ const isLandscape = () => { const dim = Dimensions.get('screen'); return dim.width >= dim.height; };Para saber cuándo cambia la orientación para cambiar la vista en consecuencia
// Event Listener for orientation changes Dimensions.addEventListener('change', () => { this.setState({ orientation: Platform.isPortrait() ? 'portrait' : 'landscape' }); });Montaje de todas las piezas
import React from 'react'; import { StyleSheet, Text, Dimensions, View } from 'react-native'; export default class App extends React.Component { constructor() { super(); /** * Returns true if the screen is in portrait mode */ const isPortrait = () => { const dim = Dimensions.get('screen'); return dim.height >= dim.width; }; this.state = { orientation: isPortrait() ? 'portrait' : 'landscape' }; // Event Listener for orientation changes Dimensions.addEventListener('change', () => { this.setState({ orientation: isPortrait() ? 'portrait' : 'landscape' }); }); } render() { if (this.state.orientation === 'portrait') { return ( //Render View to be displayed in portrait mode ); } else { return ( //Render View to be displayed in landscape mode ); } } }Como el evento definido para observar el cambio de orientación usa este comando ' this.setState() ', este método vuelve a llamar automáticamente a ' render() ' para que no tengamos que preocuparnos por renderizarlo nuevamente, todo está solucionado. .
Aquí está la respuesta de @Mridul Tripathi como un gancho reutilizable:
// useOrientation.tsx import {useEffect, useState} from 'react'; import {Dimensions} from 'react-native'; /** * Returns true if the screen is in portrait mode */ const isPortrait = () => { const dim = Dimensions.get('screen'); return dim.height >= dim.width; }; /** * A React Hook which updates when the orientation changes * @returns whether the user is in 'PORTRAIT' or 'LANDSCAPE' */ export function useOrientation(): 'PORTRAIT' | 'LANDSCAPE' { // State to hold the connection status const [orientation, setOrientation] = useState<'PORTRAIT' | 'LANDSCAPE'>( isPortrait() ? 'PORTRAIT' : 'LANDSCAPE', ); useEffect(() => { const callback = () => setOrientation(isPortrait() ? 'PORTRAIT' : 'LANDSCAPE'); Dimensions.addEventListener('change', callback); return () => { Dimensions.removeEventListener('change', callback); }; }, []); return orientation; }Luego puedes consumirlo usando:
import {useOrientation} from './useOrientation'; export const MyScreen = () => { const orientation = useOrientation(); return ( <View style={{color: orientation === 'PORTRAIT' ? 'red' : 'blue'}} /> ); }Puedes usar el onLayout :
export default class Test extends Component { constructor(props) { super(props); this.state = { screen: Dimensions.get('window'), }; } getOrientation(){ if (this.state.screen.width > this.state.screen.height) { return 'LANDSCAPE'; }else { return 'PORTRAIT'; } } getStyle(){ if (this.getOrientation() === 'LANDSCAPE') { return landscapeStyles; } else { return portraitStyles; } } onLayout(){ this.setState({screen: Dimensions.get('window')}); } render() { return ( <View style={this.getStyle().container} onLayout = {this.onLayout.bind(this)}> </View> ); } } } const portraitStyles = StyleSheet.create({ ... }); const landscapeStyles = StyleSheet.create({ ... });