Módulo 3 INTERMEDIÁRIO

Atividade 14: Menu Lateral (Drawer)

Deslize o dedo pela borda da tela e descubra configurações secretas do seu App.

🎯 Objetivos desta aula

  • Usar a biblioteca secundaria auxiliar react-native-reanimated.
  • Configurar o Navigator estilo <Drawer.Navigator />.
  • Abrir o Drawer programaticamente via Javascript e controlar sua posição (Esquerda ou Direita).

🍔 O Famoso Hamburger Menu

Aquelas 3 linhas no topo superior esquerdo da tela (Chamados de Icone Hamburger 🍔) costumam puxar um gaveteiro gigante cheio de outras funções que não couberam nas Bottom Tabs: Perfil Rápido, Logout, Configurações, Documento, Termos, etc. Esses gaveteiros são os Drawers.

Muitos apps combinam o uso das Pilhas + Abas + Gaveta. Por exemplo, o Gmail: Ele tem a Pilha (Quando você abre um email por cima do menu), ele tem Bottom Tabs para Vídeo chamada, e tem um Drawer (Gaveta) na lateral escondendo Lixeira, Spam, e Contatos!

Abertura e Fechamento Mágicos (Gestos e Códigos)

O Drawer nativo já reconhece quando os usuários Mobile deslizam o dedão para a borda do celular. Ele abre sozinho com física. Mas além desse gesto embutido, se criarmos um ícone de hamburger ou um botão no meio da tela e quisermos forçar a gaveta a abrir ou fechar, os comandos de viagem expõe os seguintes métodos:

import { useNavigation } from '@react-navigation/native'; // ou expo-router

// Recebe o gancho do roteador
const navigation = useNavigation();

// Abre a Gaveta se ela estiver fechada... (Também tem o .closeDrawer())
navigation.openDrawer(); 

// Inverte o estado atual da Gaveta (Se aberta, fecha. Se fechada, abre)
navigation.toggleDrawer();

🧐 Atenção: Por ter muitas animações complexas, a Drawer Navigation pede a instalação obrigatória de um pacote extra no Expo chamado react-native-reanimated! Sem ele o seu app quebra na hora que for rodar o Drawer nativo C++, ele não pode usar javascript simples.

💻 Exemplo Prático (Snack Clássico)

O Web-Snack não é capaz de rodar facilmente a "reanimated". Abaixo é o código base de um Drawer. Talvez no site ocorra um erro de Reanimated (Mas no App real funcionará). Múltiplos frameworks no Browser pesam!

App.js
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';

function TelaInicial({ navigation }) {
  return (
    <View style={styles.telaHome}>
      <Text style={styles.texto}>Bem-vindo!</Text>
      
      {/* Botão de abrir via Código, sem o gesto do Hamburger 🍔 */}
      <Button
        title="Forçar Abertura da Gaveta Mágica 🚪"
        onPress={() => navigation.openDrawer()}
      />
    </View>
  );
}

function TelaAjuda() {
  return (
    <View style={styles.telaAjuda}>
      <Text style={{color: 'white', fontWeight: 'bold'}}>Perguntas Frequentes (FAQ)</Text>
    </View>
  );
}

// 1. Criando a estrutura física do Drawer
const Drawer = createDrawerNavigator();

export default function App() {
  return (
    <NavigationContainer>
      {/* 2. Propriedades de como abrir o Drawer e de que lado */}
      <Drawer.Navigator 
        initialRouteName="Início"
        screenOptions={{
          drawerPosition: 'left', // right = abre na direita (bom para Canhotos ou Apps Árabes com leitura reversa)
          drawerType: 'slide', // 'slide' empurra a tela toda para o lado. 'front' vem flutuando por cima da tela
        }}
      >
        
        {/* As Telas Internas */}
        <Drawer.Screen 
          name="Início" 
          component={TelaInicial} 
        />
        
        <Drawer.Screen 
          name="Ajuda" 
          component={TelaAjuda} 
        />

      </Drawer.Navigator>
    </NavigationContainer>
  );
}

const styles = StyleSheet.create({
  telaHome: { flex: 1, backgroundColor: '#fff', justifyContent: 'center', alignItems: 'center' },
  telaAjuda: { flex: 1, backgroundColor: '#334155', justifyContent: 'center', alignItems: 'center' },
  texto: { fontSize: 22, fontWeight: 'bold', marginBottom: 20 }
});

🎮 Desafios Práticos

(Se o ambiente Snack permitir...) Teste os efeitos do seu painel lateral escondido! Modifique a mecânica física dele.

DESAFIO 1

Modificar 🛠️

  • Lá nas definições do `` principal, altere a propriedade `drawerPosition` de `'left'` (Esquerda) para `'right'`.
  • Teste no emulador se agora o Botão Hambúrguer subiu para o lado de lá, e se deslizar o dedo da direita é a chave do sucesso!
DESAFIO 2

Melhorar 🚀

  • Mude a propriedade `drawerType` para `'front'` (que sobrepõe), volte para `'slide'` (que empurra). Veja qual modelo fica mais agradável visualmente e teste o modo final: `'permanent'` (que NUNCA fecha a gaveta lateral, algo muito utilizado se o seu app estiver rodando num Tablet deitado (em landscape) onde sobra muito espaço!).
DESAFIO 3

Criar ✨

Crie um botão Mágico Alternador.

  • Já usamos a Navigation navigation.openDrawer() antes.
  • Vá na sua `function TelaInicial({navigation})`, crie um novo botão `
  • Na opção `onPress` dele, você deve evocar a função navigation.toggleDrawer(). (Esse é o comando que sempre inverte a lógica do outro independentemente de seu estado).

📝 Quiz - Menus Laterais (Drawers)