React Native - Criando layouts - Parte 1

Imagem para React Native - Criando layouts - Parte 1

React nativePostado em  6 min de leitura

Para criar um layout no React Native vamos usar o Flexbox, mas nem todos os recursos que estão na especificação do Flexbox, estão incluídos. :/

Stack Layout

Esse layout na orientação vertical empilha elementos em cima uns dos outros, enquanto que para a orientação horizontal, os elementos são colocados lado a lado. Vejamos a orientação vertical:

import React, { Component } from 'react';
import { StyleSheet, View, Dimensions } from 'react-native';

const { height } = Dimensions.get('window');
const boxCount = 3;
const boxHeight = height / boxCount;

export default class VerticalStackLayout extends Component {
  render() {
    return (
      <View style={styles.container}>
        <View style={[styles.box, styles.box1]}></View>
        <View style={[styles.box, styles.box2]}></View>
        <View style={[styles.box, styles.box3]}></View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column'
  },
  box: { height: boxHeight },
  box1: { backgroundColor: 'red' },
  box2: { backgroundColor: 'blue' },
  box3: { backgroundColor: 'green' }
});

No elemento pai(container), usaremos a propriedade flex. O valor é a quantidade de espaço que ele ocupará. Sendo 1, isso significa que ele ocupará todo o espaço disponível, desde que o elemento não tenha irmãos.

A propriedade flexDirection permite que você especifique o eixo principal do layout. Por padrão, isso é definido como column. O valor de flexDirection sendo column, significa que os elementos filhos serão dispostos verticalmente (empilhados uns sobre os outros). Se o valor for row, significa que os filhos serão dispostos horizontalmente (lado a lado).

Stack Layout Vertical

O exemplo acima mostra a maneira manual. O uso de Dimensions para calcular a largura ou a altura dos elementos falhará se o seu aplicativo suportar a orientação do dispositivo retrato e paisagem. Isso ocorre porque assim que o usuário virar seu dispositivo, a largura ou a altura que você calculou não serão atualizadas. Exemplo mudando a orientação:

Stack Layout Vertical

O Flexbox faz a computação para você, se você fornecer os valores corretos. Para alcançar o mesmo layout acima, sem usar o Dimensions, tudo o que você precisa fazer é especificar flex: 1 para todas as caixas, em vez de especificar o valor para a propriedade height:

Stack Layout Vertical

box: {
  flex: 1
},

Stack Layout Vertical

Agora podemos evoluir esse layout com o uso do flex nos elementos irmãos.

//header
box1: {
  flex: 1,
  backgroundColor: 'red',
},
//content
box2: {
  flex: 10,
  backgroundColor: 'blue',
},
//footer
box3: {
  flex: .5,
  backgroundColor: 'green',
}

Stack Layout Vertical

Tenha em mente que se conteúdo interno for maior do que a altura máxima disponível, o resto do seu conteúdo será oculto. Se você espera que seu conteúdo ultrapasse esse limite, você pode usar o componente de ScrollView, incorporado para gerar automaticamente uma barra de rolagem vertical, como em uma página da web.

Horizontal

Para implementar a orientação horizontal, basta mudar o flexDirection para row. Colocando o valor de flex do box novamente para 1, isso resulta em que 3 colunas ocuparam toda a tela.

Stack Layout Vertical

container: {
  flex: 1,
  flexDirection: 'row',
},
box: { flex: 1 },
box1: { backgroundColor: 'red' },
box2: { backgroundColor: 'blue' },
box3: { backgroundColor: 'green' }

Justificando o conteúdo

Se você deseja controlar a distribuição dos elementos filhos, é necessário utilizar a propriedade justifyContent no elemento pai.

container: {
  flex: 1,
  flexDirection: 'column',
  justifyContent: 'flex-start',
},
box: { height: boxHeight },
box1: { backgroundColor: 'red' },
box2: { backgroundColor: 'blue' },
box3: { backgroundColor: 'green' }

Stack Layout Vertical

Abaixo vamos ver os 5 valores possíveis que podem ser usados ​​com essa propriedade. Você não conseguirá ver nenhuma diferença se o valor da propriedade flex for 1, para cada um dos elementos filhos, porque eles ocupariam todo o espaço disponível.

  • flex-start: os elementos filhos são alinhados em direção ao ponto de partida. Observe o fundo branco logo abaixo do último filho. É assim que você sabe que isso está sendo usado o flex-start.
  • flex-end: os elementos filhos são alinhados em direção à linha final. Desta vez o espaço vazio estará no ponto de partida.
  • center: os elementos filhos são colocados em direção ao centro. Desta vez, o espaço vazio é dividido igualmente entre o ponto inicial e final.
  • space-around: os elementos filhos são distribuídos de modo que haveria espaço igual em cada um deles. Isso significa que os elementos na parte externa teriam menos espaço no lado externo e o espaço entre os dois filhos é duplicado.
  • space-between: os elementos filhos são distribuídos de modo que haveria uma quantidade igual de espaço entre cada um deles.

Como você pode ter notado, cada um desses valores de estilo dependem da altura ou largura dos elementos filhos. Depende da largura, se flexDirection for row e na altura se flexDirection for column.

Por exemplo, space-between realmente não terá qualquer efeito em um Stack layout vertical se cada um dos elementos filhos estiver usando flex para controlar a altura. Isso ocorre porque não haverá mais espaço entre cada elemento para ocupar.

Alinhando os itens

justifyContent e alignItems podem parecer como se estivessem fazendo o mesmo. Eles também compartilham três valores possíveis: flex-start, flex-end e center, com a adição do valor stretch na propriedade alignItems.

Stack Layout Vertical

A principal diferença entre justifyContent e alignItems é o eixo em que os elementos filhos são distribuídos. Como você vimos anteriormente, justifyContent sempre usa o eixo primário ao distribuir elementos filhos. Mas alignItems usa o eixo oposto ao primário.

Nós já sabemos que o eixo é determinado pelo flexDirection que foi definido. Então, se flexDirection for row, o eixo primário flui da esquerda para a direita. Isso significa que o eixo transversal irá fluir de cima para baixo. Por outro lado, se flexDirection é column que o eixo transversal irá fluir da esquerda para a direita.

Abaixo vamos ver alguns exemplos com justifyContent e alignItems implementados lado a lado com o flexDirection de row. O primeiro usa justifyContent enquanto o segundo usa alignItems.

  • flex-start: o posicionamento dos elementos é o mesmo, por isso que a implementação de alignItems e justifyContent, são iguais.
  • flex-end: agora começamos a ver uma diferença. Com justifyContent, os elementos filhos irão para o final da primeira linha, enquanto com alignItems os elementos filhos irão estar no início da última linha.
  • center: tem a mesma ideia do resto dos valores que usamos até agora. Com justifyContent, os itens são centrados no eixo x enquanto com alignItems, os itens estão centrados no eixo y.
  • stretch: use para que os elementos filhos se estendam para preencher o elemento pai. Este é o valor padrão para alignItems, portanto, especificar esse valor é opcional.

Stack Layout Vertical

Abaixo temos o trecho de código usado nos exemplos acima. Basta alterar os valores para o flexDirection, justifyContent e alignItems:

import React, { Component } from 'react';
import {
  StyleSheet,
  View
} from 'react-native';

export default class AlignItems extends Component {
  render() {
    return (
      <View style={styles.wrapper}>
        <View style={styles.container}>
            <View style={[styles.box, styles.box1]}></View>
            <View style={[styles.box, styles.box2]}></View>
            <View style={[styles.box, styles.box3]}></View>
        </View>
        <View style={styles.container2}>
            <View style={[styles.box, styles.box1]}></View>
            <View style={[styles.box, styles.box2]}></View>
            <View style={[styles.box, styles.box3]}></View>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  wrapper: {
    flex: 1
  },
  container: {
    flex: .5,
    flexDirection: 'row',
    justifyContent: 'flex-start',
    borderBottomWidth: 1,
    borderBottomColor: '#000'
  },
  container2: {
    flex: .5,
    flexDirection: 'row',
    alignItems: 'flex-start'
  },
  box: {
    width: 100,
    height: 100
  },
  box1: { backgroundColor: '#2196F3' },
  box2: { backgroundColor: '#8BC34A' },
  box3: { backgroundColor: '#e3aa1a' }
});

Se você quiser especificar o alinhamento de elementos filhos dentro de um elemento pai, você pode usar a propriedade alignSelf. Todos os valores possíveis de alignItems são aplicáveis ​​a esta propriedade. Então, por exemplo, você pode alinhar um único elemento à direita do seu elemento pai, enquanto todos os restantes estão alinhados à esquerda.

Conclusão

Nessa primeira parte, implementamos o Stack layout. E na segunda parte, vamos continuar vendo outros tipos de layout que podemos fazer.

O repositório nexus-react-native/04-how-to-create-layouts, está a disposição para praticar. :)