A navegação na barra inferior é essencial atualmente, pois vivemos numa época em que os celulares estão com telas cada vez maiores e esticadas. Desse modo, abandonamos a proporção 16:9 e estamos utilizando variações próximas do 21:9, pois as telas estão mais altas.

Com isso, o acesso a parte superior da tela pode ficar um pouco complicado para quem tem mãos pequenas, principalmente quando precisamos utilizar o celular com apenas uma mão. Por isso a barra de navegação inferior vai ajudar bastante na navegação do aplicativo.

Criando o projeto

Vou começar criando um projeto chamado “navbar”, mas podem nomear da forma como acharem melhor, da forma como sempre é feita, a partir do comando “flutter create navbar”.

Após a criação do projeto vamos fazer o básico. Primeiramente, vou deletar a pasta “test” e editar o arquivo “main.dart”, para deixá-lo da seguinte forma:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Bottom Navigation',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
        brightness: Brightness.dark,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Bottom Navigation")),
    );
  }
}

A tela ficará mais ou menos assim:

Tela inicial do App

Implementando a Bottom Navigation Bar

Em seguida, vamos inserir o seguinte trecho de código abaixo do AppBar do nosso Scaffold:

bottomNavigationBar: BottomNavigationBar(
        currentIndex: 0,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_1),
            label: "Red",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_2),
            label: "Green",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_3),
            label: "Blue",
          ),
        ],
      ),

O código completo ficará assim:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Bottom Navigation',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
        brightness: Brightness.dark,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Bottom Navigation")),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: 0,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_1),
            label: "Red",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_2),
            label: "Green",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_3),
            label: "Blue",
          ),
        ],
      ),
    );
  }
}

Dessa forma o resultado será o seguinte:

App com barra inferior

Agora, dentro da pasta “lib” vamos criar uma pasta chamada “screens” e dentro dela vamos criar 3 arquivos, que são:

red.dart

import 'package:flutter/material.dart';

class Red extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(color: Colors.red);
  }
}

green.dart

import 'package:flutter/material.dart';

class Green extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(color: Colors.green);
  }
}

blue.dart

import 'package:flutter/material.dart';

class Blue extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(color: Colors.blue);
  }
}

Agora, vamos criar uma lista com todas as nossas telas dentro do nosso Widget principal, logo acima do “@override”, dessa forma:

final List<Widget> _telas = [
    Red(),
    Green(),
    Blue(),
  ];

Lembrando que é necessário também fazer o import de cada uma dessas páginas. No fim o nosso arquivo main ficará dessa forma:

import 'package:flutter/material.dart';
import 'screens/red.dart';
import 'screens/green.dart';
import 'screens/blue.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Bottom Navigation',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
        brightness: Brightness.dark,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<Widget> _telas = [
    Red(),
    Green(),
    Blue(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Bottom Navigation")),
      body: _telas[0],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: 0,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_1),
            label: "Red",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_2),
            label: "Green",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_3),
            label: "Blue",
          ),
        ],
      ),
    );
  }
}

O Resultado será o seguinte:

Tela vermelha

Agora vamos criar uma variável que vai armazenar a página atual que estamos navegando, ou seja, o índice a aba atual. Basta adicionar o seguinte código logo acima da lista que criamos antes:

int _paginaAtual = 0;

Abaixo da variável vamos criar a função que vai fazer com que a mudança de abas aconteça modificando o valor do índice:

void aoMudarDeAba(int indice) {
    setState(() {
      _paginaAtual = indice;
    });
  }

Para finalizar, vamos atualizar o Widget BottomNavigationBar. Primeiro, vamos alterar o valor que está no Body para apontar para a variável que indica a página. Depois, vamos modificar o “currentIndex” da mesma que modificamos no Body. Por fim, vamos adicionar a propriedade “onTap” e apontá-la para a função que criamos anteriormente.

No final o código do Scaffold ficará da seguinte forma:

return Scaffold(
      appBar: AppBar(title: Text("Bottom Navigation")),
      body: _telas[_paginaAtual],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _paginaAtual,
        onTap: aoMudarDeAba,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_1),
            label: "Red",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_2),
            label: "Green",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.filter_3),
            label: "Blue",
          ),
        ],
      ),
    );

E o Resultado será o esperado, sempre que trocarmos de página, a cor do fundo dela irá mudar!

Tela azul na Navegação com Barra Inferior

Conclusão

Acho super interessante essa solução de colocar a navegação com barra inferior e como ela funciona. Existem diversos Apps no mercado que utilizam essa solução, como o Intagram, o Spotify ou o Twitter. O usuário poder ter acesso a todas as funções do App sem precisar se esticar todo pra alcançar algum botão!

Então é isso galera, espero que tenham gostado da dica e até a próxima!