Flutter UI Essentials – Navigation Bar

Tempo de leitura: 4 minutes

Flutter NavigationBar é um componente de 3 materiais de design. Foi introduzido como substituto do widget BottomNavigationBar. De qualquer forma, uma barra de navegação na parte inferior da tela é um método adequado para se mover entre as telas do aplicativo.

 

O que há de novo

  • O nome — Barra de navegação inferior à barra de navegação
  • Novos mapeamentos de cores
  • Elevação sem sombra
  • A altura do layout é mais alta
  • O ícone ativo será indicado com um retângulo de cantos arredondados (em forma de pílula)

O que devemos considerar de acordo com o design do material

  • Adicione mais de 3, mas menos de cinco destinos
  • Use apenas para dispositivos móveis e guias pequenas
  • Os destinos da barra de navegação não devem ser roláveis. Os ícones e rótulos devem caber na tela
  • É melhor usar cores diferentes para a tela, assim podemos ver a barra de navegação separadamente
  • Para destinos ativos, os ícones de cor de preenchimento são melhores. Se não tivermos ícones significativos, a melhor maneira é emparelhar o ícone com um rótulo
  • Não devemos usar cores múltiplas ou de baixo contraste na barra de navegação para ícones
  • Usar o indicador ativo apenas para os destinos ativos dará uma ideia clara sobre a tela atual
  • A expansão da animação do indicador ativo deve ser limitada a um eixo
  • Use rótulos curtos e significativos para indicar a finalidade do destino
  • Não devemos agrupar, truncar ou encolher rótulos mais longos para caber em uma única linha
  • Podemos adicionar um FAB alinhado à direita acima da barra de navegação
  • Devemos usar o mínimo de altura padrão sem tornar a altura da barra densa
  • Não devemos permitir que os usuários mudem de tela com um gesto de deslizar

Podemos encontrar um conjunto de diretrizes aqui com um guia de imagem atraente.

Tema da barra de navegação — A barra de navegação não ajusta o tamanho com

O NavigationBarThemeData ou os parâmetros controlarão os estilos do Navigation bar.

O BottomNavigationBar usa widgets BottomNavigationBarItem. A NavigationBar usa NavigationDestination. NavigationDestination exibirá um rótulo abaixo de um ícone.

 

Construtores

NavigationBar({Key? key, 
    Duration? 
    animationDuration, 
    int selectedIndex = 0, 
    required List<Widget> destinations, 
    ValueChanged<int>? onDestinationSelected, 
    Color? backgroundColor, 
    double? elevation, 
    Color? shadowColor, 
    Color? surfaceTintColor, 
    double? height, 
    NavigationDestinationLabelBehavior? labelBehavior})

Passemos ao código.

Minha demonstração da barra de navegação inferior.

bottomNavigationBar: NavigationBar(
   onDestinationSelected: (int index) {
     setState(() {
       currentPageIndex = index;
     });
   },
   selectedIndex: currentPageIndex,
   destinations: const <Widget>[
     NavigationDestination(
       selectedIcon: Icon(Icons.home),
       icon: Icon(Icons.home_outlined),
       label: 'Home',
     ),
     NavigationDestination(
       selectedIcon: Icon(Icons.account_circle),
       icon: Icon(Icons.account_circle_outlined),
       label: 'Profile',
     ),
     NavigationDestination(
       selectedIcon: Icon(Icons.image),
       icon: Icon(Icons.image_outlined),
       label: 'Gallery',
     ),
   ],
 ),

Destinos

body: <Widget>[
  const HomeScreen(),
  const ProfileScreen(),
  GalleryScreen()
][currentPageIndex]

Ele criará uma barra de navegação inferior como esta.

Obrigado pelo seu tempo!!!

Você pode encontrar o código completo abaixo:

import 'package:flutter/material.dart';

void main() => runApp(const ExampleApp());

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.green),
      home: const NavigationExample(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class NavigationExample extends StatefulWidget {
  const NavigationExample({super.key});

  @override
  State<NavigationExample> createState() => _NavigationExampleState();
}

class _NavigationExampleState extends State<NavigationExample> {
  int currentPageIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Navigation bar demo"),
      ),
      floatingActionButton: FloatingActionButton(onPressed: (){}, child: const Icon(Icons.add),),
      bottomNavigationBar: NavigationBar(
        onDestinationSelected: (int index) {
          setState(() {
            currentPageIndex = index;
          });
        },
        selectedIndex: currentPageIndex,
        destinations: const <Widget>[
          NavigationDestination(
            selectedIcon: Icon(Icons.home),
            icon: Icon(Icons.home_outlined),
            label: 'Home',
          ),
          NavigationDestination(
            selectedIcon: Icon(Icons.account_circle),
            icon: Icon(Icons.account_circle_outlined),
            label: 'Profile',
          ),
          NavigationDestination(
            selectedIcon: Icon(Icons.image),
            icon: Icon(Icons.image_outlined),
            label: 'Gallery',
          ),
        ],
      ),
      body: <Widget>[
        const HomeScreen(),
        const ProfileScreen(),
        GalleryScreen()
      ][currentPageIndex],
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;
    return SingleChildScrollView(
      padding: const EdgeInsets.all(20),
      child: Column(
        children: [
          Container(
            height: 200.0,
            decoration: const BoxDecoration(
              image: DecorationImage(
                fit: BoxFit.cover,
                image: AssetImage("assets/animals/ani-5.jpg"),
              ),
              borderRadius: BorderRadius.all(Radius.circular(12.0)),
            ),
          ),
          const SizedBox(
            height: 20,
          ),
          SizedBox(
            width: width,
            height: height / 3,
            child: Card(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(12.0),
              ),
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      "Recommended for you",
                      style: TextStyle(fontWeight: FontWeight.w600),
                    ),
                    const SizedBox(height: 10),
                    Row(
                      children: [
                        Expanded(
                          child: Container(
                            height: height / 6,
                            decoration: const BoxDecoration(
                              image: DecorationImage(
                                fit: BoxFit.cover,
                                image: AssetImage("assets/animals/ani-1.jpg"),
                              ),
                              borderRadius:
                                  BorderRadius.all(Radius.circular(12.0)),
                            ),
                          ),
                        ),
                        const SizedBox(
                          width: 10,
                        ),
                        Expanded(
                          child: Container(
                            height: height / 6,
                            decoration: const BoxDecoration(
                              image: DecorationImage(
                                fit: BoxFit.cover,
                                image: AssetImage("assets/animals/ani-3.jpg"),
                              ),
                              borderRadius:
                                  BorderRadius.all(Radius.circular(12.0)),
                            ),
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(
                      height: 10,
                    ),
                    const Text(
                        "Lorem Ipsum is simply dummy text of the printing and typesetting industry.")
                  ],
                ),
              ),
            ),
          )
        ],
      ),
    );
  }
}

class ProfileScreen extends StatelessWidget {
  const ProfileScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Center(child: Icon(Icons.account_circle_outlined));
  }
}

class GalleryScreen extends StatelessWidget {
  GalleryScreen({Key? key}) : super(key: key);
  final List<String> imageList = [
    "assets/animals/ani-1.jpg",
    "assets/animals/ani-2.jpg",
    "assets/animals/ani-3.jpg",
    "assets/animals/ani-4.jpg",
    "assets/animals/ani-5.jpg",
    "assets/animals/ani-6.jpg",
    "assets/animals/ani-7.jpg",
  ];

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      padding: const EdgeInsets.all(20),
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        mainAxisSpacing: 10,
        crossAxisSpacing: 6,
      ),
      itemCount: imageList.length,
      itemBuilder: (context, index) {
        return Container(
          width: 100,
          height: 200,
          decoration: BoxDecoration(
              borderRadius: const BorderRadius.all(Radius.circular(12.0)),
            image: DecorationImage(
              image: AssetImage(imageList[index]), fit: BoxFit.cover
            )
          ),
        );
      },
    );
  }
}

 

 

Créditos da imagem

https://unsplash.com/photos/HsXPfq5lKHc?utm_source=unsplash

https://unsplash.com/photos/JuoE5jHlcHs?utm_source=unsplas

hhttps://unsplash.com/photos/JuoE5jHlcHs?utm_source=unsplash

https://unsplash.com/photos/JuoE5jHlcHs?utm_source=unsplash

https://unsplash.com/photos/sJ3yEZWN8fg?utm_source=unsplash

https://unsplash.com/photos/rOHMzMN-67c?utm_source=unsplash

https://unsplash.com/photos/Jb0PpM5uLCQ?utm_source=unsplash