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.

Dica importante: nesta atividade, você vai continuar no mesmo projeto Expo iniciado na Atividade 11 e reaproveitado nas Atividades 12 e 13. O objetivo agora é evoluir esse mesmo app até a Atividade 15.

🎯 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 no Projeto Local

Drawer é conteúdo para projeto local no Expo. Antes de testar, instale as dependências em blocos separados:

1. Drawer Navigator
npx expo install @react-navigation/drawer
2. Animações e gestos
npx expo install react-native-reanimated react-native-worklets react-native-gesture-handler

Como você deve fazer: mantenha o arquivo app/index.js, crie um novo arquivo app/ajuda.js e substitua apenas o conteúdo do arquivo app/_layout.js.

Importante: como você vai continuar usando Expo Router, faça as alterações só nos arquivos mostrados abaixo. Você não precisa voltar para App.js.

app/_layout.js
import { Drawer } from 'expo-router/drawer';

export default function Layout() {
  return (
    <Drawer
      screenOptions={{
        drawerPosition: 'left',
        drawerType: 'slide',
        headerStyle: { backgroundColor: '#0f172a' },
        headerTintColor: '#ffffff',
        drawerActiveTintColor: '#8b5cf6',
        drawerInactiveTintColor: '#94a3b8',
        drawerStyle: { backgroundColor: '#111827' }
      }}
    >
      <Drawer.Screen
        name="index"
        options={{ title: 'Início', drawerLabel: 'Início' }}
      />

      <Drawer.Screen
        name="ajuda"
        options={{ title: 'Ajuda', drawerLabel: 'Ajuda' }}
      />
    </Drawer>
  );
}
app/index.js
import { View, Text, Button, StyleSheet } from 'react-native';
import { useNavigation } from 'expo-router';

export default function Home() {
  const navigation = useNavigation();

  return (
    <View style={styles.container}>
      <Text style={styles.texto}>Bem-vindo!</Text>
      <Button
        title="Abrir Menu Lateral"
        onPress={() => navigation.openDrawer()}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#ffffff',
    justifyContent: 'center',
    alignItems: 'center'
  },
  texto: {
    fontSize: 22,
    fontWeight: 'bold',
    marginBottom: 20
  }
});
app/ajuda.js
import { View, Text, StyleSheet } from 'react-native';

export default function Ajuda() {
  return (
    <View style={styles.container}>
      <Text style={styles.texto}>Perguntas Frequentes (FAQ)</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#334155',
    justifyContent: 'center',
    alignItems: 'center'
  },
  texto: {
    color: 'white',
    fontWeight: 'bold',
    fontSize: 20
  }
});

🎮 Desafios Práticos

Teste os efeitos do seu painel lateral no projeto local e compare como cada configuração altera a mecânica visual 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)