Introdução ao React Native – Parte 4

E chegamos à quarta parte da minha série sobre como construir aplicativos móveis usando React Native. Para quem está chegando agora, não comece por esse post, mas ao invés disso, use os links abaixo para conhecer os outros capítulos da série.

E agora, continuando o que estávamos vendo, recém havíamos criado uma segunda tela, Form.js, em nosso app, mas ainda não tínhamos como navegar até ela.

Vamos mudar isso!

Navegando pelo App

Para fazer a navegação entre telas existem diversas formas e eu optei por lhe trazer uma que acredito ser simples, usando a lib React Navigation. Vamos instalar primeiro a lib principal:

Esta lib instala uma série de dependências-chave para que tenhamos os comportamentos nativos de navegação/transição de telas. Uma vez com ela instalada, rode este comando para instalar mais algumas dependências necessárias pelo Expo.

Estas libs vão permitir que a gente crie recursos nativos de navegação. Mesmo que a gente não venha a utilizar todas estas bibliotecas diretamente, muitas delas são necessárias para a compilação correta do nosso app. A título de curiosidade, temos nesse comando:

  • react-native-gesture-handler: para suportar gestos do usuário, como os de navegação;
  • react-native-reanimated: animações de transição;
  • react-native-screens: gestão nativa de telas;
  • react-native-safe-area-context: gestão da área “segura” de uso, por causa daquelas telas esquisitas dos smartphones mais modernos (que não são mais retângulos simples);
  • masked-view: permite máscaras de interface, para incluir views dentro;

E por fim, uma última lib para definir como a navegação será gerenciada pelo React Native.

Esta libs faz com que a navegação tenha o comportamento em pilha/stack, onde cada nova tela acessada é empilhada sobre a anterior, permitindo voltar na tela anterior com os recursos de cada plataforma, como o botão de Back/Voltar do Android. Outras opções de navegação incluiriam navegação por abas e por sidemenu, por exemplo, mas ficam para outra oportunidade.

Depois de instalar todas estas libs, não esqueça de reiniciar o Metro Bundler e scanear novamente o QRCode para atualizar completamente nosso Expo Client. É comum ele se perder depois da instalação de pacotes novos.

Para configurar nossa navegação, crie um arquivo Routes.js na raiz da sua aplicação, com o seguinte conteúdo.

O que temos aqui em cima é, primeiramente, os imports necessários referente aos pacotes que instalamos anteriormente e depois referente a todas as telas que queremos configurar navegação no nosso app.

Logo abaixo, criamos um objeto de navegação em pilha (stack) e depois a estrutura de navegação em si, que apesar de parecer complexa, é bem simples e repetitiva. Dentro do NavigationContainer temos um AppStack.Navigator e dentro dele, uma linha para cada tela (AppStack.Screen) com o nome da tela (único) e componente a ser renderizado (os que importamos no início do arquivo).

Dica: dentro do AppStack.Navigator é possível determinar alguns estilos globais para a aplicação, como a statusbar, a cor de fundo das telas, etc através de uma propriedade chamada screenOptions. Além disso, note que usei uma opção headerMode também, para evitar que ele adicionasse uma barra superior automaticamente, sendo que já temos a nossa.

E por fim, para que nossas rotas passem a “existir” no nosso app, vamos voltar ao App.js, vamos importar esse nosso módulo de rotas e vamos chamá-lo no retorno da função App.

Se você olhar agora o seu smartphone, vai notar que nada mudou e que mesmo não referenciando mais a Home no nosso App.js, ela ainda está lá como tela default, isso pois é a primeira no nosso arquivo de rotas. Mas ainda fica a pergunta, como vamos fazer para trocar de uma tela para outra?

Vamos arrumar isso na nossa Home.js, iniciando com um novo import (useNavigation).

E agora vamos usar esta função dentro da function Home, como abaixo.

Este objeto navigation possui uma function navigate que espera por parâmetro o name da tela que queremos (o mesmo name que definimos no arquivo Routes.js). Sendo assim, podemos chamar esta função em um segundo botão dentro da nossa Home.js:

Agora sim, além do efeito óbvio de aparecer um segundo botão na tela, ao pressioná-lo com o dedo, você navegará para a tela Form.js, com a animação de transição nativa do dispositivo, bem como o comportamento nativo de voltar para a tela anterior arrastando o dedo (iOS) ou apertando o botão de voltar (Android).

Mas se isso não for o bastante e você quiser colocar um botão de voltar na tela Form.js, você importar o mesmo useNavigation e chamar navigation.goBack() ao pressionar seu botão de voltar. Não vou entregar pronto aqui que é pra você exercitar!

Criando apps para empresas com Android

Lidando com imagens

Agora que temos esta página de cadastro, vamos criar um formulário nela, bem simples, apenas para exercitar alguns conceitos. Vou aproveitar esta oportunidade para mostrar alguns truques novos, a começar pelo uso de imagens em nosso app, algo importantíssimo.

Crie uma nova pasta chamada Assets dentro de Pages. Sim, eu sei que na raiz da aplicação tem outra pasta chamada assets, mas ignore ela, tem outra função. Todos os recursos (assets) estáticos da nossa aplicação, como imagens, ficarão aqui dentro, a começar por uma imagem de cadastro de usuário que deixaremos no topo da tela e aqui vai a primeira dica sobre imagens: sempre tenha 3 tamanhos para a mesma imagem, como no caso abaixo que peguei do site findicons.com.

Cadastrar Usuário
Cadastrar Usuário

Coloque os 3 tamanhos na pasta Pages/Assets, sendo o menor tamanho com o nome original, o segundo tamanho com o mesmo nome mas terminado em @2x e o terceiro tamanho (maior de todos) com o mesmo nome mas terminado em @3x, como abaixo.

Usando este padrão, poderemos referenciar somente a primeira deles na nossa aplicação e o React Native automaticamente selecionará a imagem certa conforme a resolução e densidade de pixels da tela do dispositivo que estiver rodando o nosso app.

Mas como vamos referenciar essas imagens na nossa tela?

Vamos voltar ao Form.js e vamos substituir o código antigo por este:

O que há de novo aqui? Primeiro, dois imports: o componente Image (do React Native) e a imagem, que é importada do mesmo jeito de um componente comum.

Depois, dentro da function Form, eu incluí um componente Image com o source (fonte) apontando para a imagem que importamos e definindo alguns estilos referenciados mais abaixo, estilos esses que alteram o texto da tela também.

O resultado você confere abaixo.

Imagem de Cadastro
Imagem de Cadastro

Além desse uso mais direto da imagem, podíamos ter imagens em segundo plano (background) e até mesmo imagens como botões. Mas esses exemplos ficam para um segundo momento.

Criando o formulário

Agora que criamos o topo do nosso formulário, está na hora de criar o formulário em si. Vai ser um formulário simples, mas ao mesmo tempo bem didático: dois campos de texto e uma lista de seleção. Para que a gente possa usar uma lista de seleção, componente que não existe nativo no React Native, instale mais uma dependência no seu projeto, a react-native-picker-select:

Além da lista de seleção, os demais componentes que vamos usar são nativos, então basta importá-los corretamente, como abaixo.

Vamos começar de maneira simples, definindo dois inputs de texto comuns e um botão, mas todos estilizados.

O TextInput é um campo de texto simples, sendo que a propriedade placeholder é o texto padrão que aparece no seu interior até que o usuário digite algo. Apenas ajustei o campo da idade para ser numérico, usando a propriedade keyboardType mas poderíamos ter adicionado muitas outras propriedades como maxLength (número máximo de caracteres no campo), autoCorrect (corretor ortográfico do smartphone), autoCapitalize (para usar apenas maiúsculas), entre outras.

O TouchableOpacity é um botão que já usamos anteriormente. Os estilos referenciados estão abaixo.

O que temos de novidade aí?

  • alignItems: ‘stretch’, faz com que o componente ocupe toda largura da tela;
  • borderRadius: define um ângulo de arredondamento da borda;
  • paddingHorizontal: margem interna nas extremidades direita e esquerda;

O resultado, temos abaixo.

Aparência do Formulário
Aparência do Formulário

Pera, mas tem um componente diferente ali…que “RS” é aquele no final do screenshot do formulário?

Esse componente de lista é um pouco mais complexo que os demais, a começar pois ele depende de um array de valores que vamos definir fora do mesmo, mas dentro da function Form. Também aproveito para declarar o placeholder que será utilizado por ele.

E também, ele depende de uma folha de estilos específica para ele, contendo um objeto inputIOS e um inputAndroid, como abaixo. Esses nomes não são opcionais, são esperados pelo componente para estilizá-lo.

Agora que criamos todos os recursos necessários para nosso picker, vamos adicioná-los na tela desta forma.

Atenção ao placeholder, que é o objeto padrão do componente (declaramos anteriormente, lembra?), ao onValueChange que é a function que vai ser disparada toda vez que for selecionada uma opção (nada por enquanto), a propriedade items que recebe nosso array de estados e a propriedade style que recebe a nossa stylesheet específica para o componente.

O comportamento desse componente você confere na imagem abaixo (no caso do iOS, no Android a aparência é diferente).

Picker Select
Picker Select

Dica: caso o formulário de alguma aplicação sua fique muito grande e parte dele fique fora da área de visão da tela, use uma ScrollView ao invés da View tradicional para a tela se tornar “rolável”. Outra dica é se o teclado ficar acima dos campos quando for digitar, você pode usar o KeyboardAvoidingView por fora dos campos, como um contâiner.

Eu coloquei uma lista fixa de UFs, o que é ok para um campo como esse, mas já pensou se os valores do seu campo tivessem de ser dinamicamente carregados através de um banco de dados fora do app?

E o nosso botão de Salvar, onde que ele vai salvar?

Essas e outras perguntas serão respondidas no próximo capítulo desta nossa saga de aprendizado que você confere clicando neste link!

Gostou do tutorial de hoje? Conheça meu curso online de Node.js clicando no banner abaixo.

Curso Node.js e MongoDB