Como criar layouts responsivos no React Native

Publicados: 2019-10-10

Os desenvolvedores de aplicativos nativos sempre se esforçam muito para criar aplicativos bonitos com uma interface de usuário avançada e estável em todos os dispositivos compatíveis. Para iOS, isso significa apenas alguns dispositivos. Para Android, pode ser mais de uma dúzia.

Ao desenvolver um aplicativo com o React Native, você pode somar esses números e depois multiplicá-los por dois, pois todos os dispositivos podem ser girados. Neste pequeno artigo, tentarei mostrar algumas ferramentas e truques que podem ajudá-lo a lidar com a enorme variedade de dispositivos sem enlouquecer!

1. Em primeiro lugar, FLEXBOX

Os componentes podem controlar o layout com um algoritmo flexbox. Ele foi criado para manter as proporções e a consistência do layout em diferentes tamanhos de tela.

O Flexbox funciona de maneira muito semelhante ao CSS na Web com apenas algumas exceções que são realmente fáceis de aprender. Quando flex prop é um número positivo, os componentes se tornam flexíveis e se ajustam à tela em relação ao seu valor flex. Isso significa que flex equivale a flexGrow: [número], flexShrink: 1, flexBasis: 0.

Quando flex: 0 — é dimensionado de acordo com a altura e a largura e é inflexível.
Se flex for um número negativo, ele também usará altura e largura, mas se não houver espaço suficiente, ele encolherá para minHeight e minWidth.

Existem poucas propriedades principais fornecidas pelo flexbox, então vamos analisá-las!
Flex descreve como os elementos dividem o espaço entre eles. Como mencionado acima, é limitado a números únicos.

Se todos os elementos tiverem flex: 1 eles terão a mesma largura.
Em outros casos, eles dividirão a soma do flex entre si

Todos os elementos com flex: 1
Elementos com flex: 1 e flex: 2

Direção flexível — podemos escolher uma linha ou coluna (você também pode definir o inverso) para definir seu eixo principal ao longo do qual seu conteúdo será colocado. Por padrão, o flexDirection é definido como uma coluna em vez de uma linha — o que é causado pela natureza da tela em dispositivos móveis.

justifyContent — este prop ajuda você a posicionar o conteúdo dentro de um container ao longo do eixo principal. Você pode verificar alguns canais possíveis abaixo:

justificarConteúdo - 3 posicionamentos possíveis

Alinhar itens — funciona da mesma forma que justifyContent, mas alinha itens no eixo perpendicular ao eixo principal.

Flex prop fazem um bom trabalho em manter as proporções entre os elementos. Independente do tamanho da tela. O FlexDirection e o justifyContent mantêm o comportamento do layout consistente.

Existem muitos outros adereços flexbox. Toquei apenas em alguns para mostrar como eles podem ser úteis.

2. Proporção

Outro acessório legal é a proporção (está disponível apenas no React Native), que ajuda a manter as proporções de seus elementos sob controle. Se você conhece apenas uma dimensão do seu elemento (largura ou altura), ele mantém a segunda dimensão em relação à que você já conhece.

Exemplo de proporção

3. Dimensões da Tela

É ótimo quando seus designs são os mesmos para ambas as plataformas e todos os tipos de dispositivos (celulares, tablets, iPads). No entanto, às vezes temos que lidar com layouts diferentes para dimensões de tela ou tipos de dispositivos específicos.

Por padrão, o React Native não fornece propriedades que respondam claramente qual dispositivo ou qual é o tamanho da tela. Mas existe um remédio para isso.

Para descobrir quais são as dimensões da tela, podemos usar a API Dimensions.

 import { Dimensions } from 'react-native'; const {width, height} = Dimensions.get('window');

Desde o React Native 0.61, você também pode usar um gancho.

 const {width, height} = useWindowDimensions();

Assim que obtivermos a largura dos tamanhos de tela de intervalo suportados, você poderá escolher pontos de interrupção a partir dos quais seu layout pode ser alterado. Você pode fornecer estilos diferentes para componentes ou ocultar algumas partes da tela. Esse é um comportamento semelhante às consultas de mídia usadas em CSS.

 import { Text, View, Dimensions } from 'react-native'; class App extends PureComponent { constructor(props) { super(props); this.state = { width: Dimensions.get('window').width }; } render() { return ( <View> {this.state.width < 320 ? <Text>width of the past</Text> : <Text>how big is big enough?</Text>} </View> ); } }

4. Detecte a Plataforma

Além do tamanho da tela, você também pode alterar o layout dependendo de qual aplicativo de plataforma é iniciado. Para conseguir isso, podemos usar o módulo Platform.

Há muitos casos em que pode ser usado:
Na função de renderização do componente:

 <View> {Platform.OS === 'ios' ? <Text>Hi Apple!</Text> : <Text>Hi Android!</Text>} </View>

Em estilos:

 cube: { width: Platform.OS === 'ios' ? 200 : 300, aspectRatio: 1 }

O módulo Platform fornece um método select que pode aceitar qualquer tipo de argumentos. Com essa flexibilidade, podemos obter o mesmo efeito acima, mas com um código mais limpo:

 const Logo = Platform.select({ ios: () => require('Apple'), android: () => require('Android'), })(); <Logo />;

Em estilos:

 import {Platform, StyleSheet} from 'react-native'; const styles = StyleSheet.create({ container: { flex: 1, ...Platform.select({ ios: { backgroundColor: 'red', }, android: { backgroundColor: 'blue', }, }), }, });

5. Rotação do dispositivo

Muitos aplicativos podem funcionar no modo retrato e paisagem. Se este for o caso do seu aplicativo, você deve garantir que o layout não seja interrompido ao alterar a orientação. Como você pode esperar, às vezes o layout pode mudar drasticamente quando você vira o dispositivo. Seus componentes podem precisar de um estilo diferente dependendo da orientação. Infelizmente, por padrão, a rotação do dispositivo não aciona uma nova renderização. É por isso que tem que ser manuseado manualmente. Já temos o conhecimento necessário para construir o nosso e é bem fácil!

 class RotateComponent extends PureComponent { constructor(props) { super(props); this.state = { orientation: '' }; } getOrientation = () => { if (Dimensions.get('window').width < Dimensions.get('window').height) { this.setState({ orientation: 'portrait' }); } else { this.setState({ orientation: 'landscape' }); } }; componentDidMount() { Dimensions.addEventListener('change', this.getOrientation); } render() { return ( <Text>{this.state.orientation}</Text> ); } }

Se você precisar dar suporte à mudança de orientação em todo o aplicativo, é uma boa ideia usar o HOC para injetar orientação.

const HOC = WrappedComponent => class extends PureComponent { constructor(props) { super(props); this.state = { orientação: ” }; } componentDidMount() { Dimensions.addEventListener('change', this.getOrientation); } getOrientation = () => { if (Dimensions.get('window').width ; } };

Isso é tudo! Você também pode passar getOrientation para a prop onLayout exposta pelo componente View. Ele é acionado a cada mudança de layout, portanto, deve ser usado com cuidado. A decisão é sua!

Ícone de aplicativos nativos

Curioso sobre o React Native?

Saber mais

Se você quiser aproveitar a orientação em seus estilos, lembre-se de que devem ser estilos inline. Já sabemos como acionar uma rerenderização do layout quando o dispositivo é girado, mas os estilos são carregados apenas uma vez. É por isso que os estilos que afetam o layout na rotação devem ser colocados em linha.

Como você pode esperar, uma enorme comunidade React Native já fornece pacotes que resolvem muitos dos problemas mencionados aqui. Você pode conferir aqui ou aqui para citar apenas alguns.