Flutter - Material Design com Scaffold
Hoje veremos como usar o widget Scaffold do Material Design no Flutter. |
|
O que é o Flutter ?
O Flutter é um
SDK de aplicativo móvel do Google que ajuda a criar aplicativos móveis modernos
para iOS e Android usando uma única (quase) base de código.
Ao contrário de outros frameworks como o React Native, ele não usa JavaScript
como uma linguagem de programação nem precisa de uma ponte de interpretação para
converter código JavaScript em código nativo, em vez disso, ele utiliza a
linguagem Dart e compila
diretamente em binários arms e é executado na plataforma nativa.
Se você não conhece o Flutter veja o meu artigo : Flutter - Primeiros contatos e impressões
Material Design
Antes de entrar no assunto do artigo, o widget Scaffold, precisamos apresentar o Material Design.
"Material Design" é uma "linguagem de design" desenvolvida pelo Google. Essa nova metodologia de design foi criada em 2014 e hoje é uma das maiores tendências no design.
O termo Material Design tem a ver com a criação de uma experiência de usuário onipresente e intuitiva. Para detalhes veja o site: https://material.io/design
Alguns dos principais recursos que um aplicativo com tema Material Desing deve ter são:
Scaffold
No Flutter, o
widget Scaffold implementa a estrutura do layout
visual do Material Design básico e permite definir
outros widgets do Material Design no seu interior.
O widget Scaffold é bom o suficiente para criar um
aplicativo móvel de uso geral, e, contém quase tudo que você precisa para criar
um aplicativo funcional e responsivo.
Em geral usamos o MaterialApp uma vez na aplicação, e, o widget Scaffold para cada tela que desejamos desenhar.
Este widget possui diversos parâmetros em seu construtor. Neste artigo veremos os seguintes parãmetros :
Podemos ver o uso de dois parâmetros mínimos, os widgets AppBar e Body, em um trecho de código padrão :
mport 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor : Colors.blue
),
home : Scaffold (
appBar: AppBar(
title: Text("Ola Flutter"),
),
body: Container(
color: Colors.orange,
)
)
);
}
}
|
Abaixo temos a figura que exibe a hierarquia do widget Scaffold :
A seguir vejamos cada um deles.
1- AppBar e Body
Nenhuma
aplicação Scaffold está completa sem usar
AppBar e Body, pois são os widgets mínimos que
precisam ser usados para criar um Design de Material Design.
Enquanto parâmetro body pode usar qualquer widget,
o parâmetro appbar só pode usar o widget AppBar
como entrada. Embora o próprio AppBar utilize
vários argumentos, é possível criar um AppBar vazio
para fins de visualização.
Aqui está como podemos usar Scaffold com appbar e body:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body:Text("Flutter - Scaffold"))
);
}
}
|
Embora o widget AppBar ofereça muitas funcionalidades interessantes, no entanto, aqui forneceremos um título simples para o AppBar usando o parâmetro title do construtor:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Scalffold App"),
),
body:Text("Flutter - Scaffold"))
);
}
}
|
Podemos aplicar várias permutações e combinações à exibição do AppBar, como alterar a cor do plano de fundo para laranja e usar ícones (ícone home) em vez de texto como título.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title : Icon(Icons.home), backgroundColor: Colors.orange ), body:Text("Flutter - Scaffold")) ); } } |
O body pode ter qualquer widget de propósito geral e, a escolha vai depender das informações que queremos exibir em nosso aplicativo.
2- Float Action Button
Um Float
action Button ou botão de ação flutuante, é um botão de ícone circular que é
exibido o tempo todo e geralmente serve para promover uma ação primária ou mais
amplamente usada na tela.
Este botão é criado usando o widget FloatingActionButton() com um mínimo de dois
parâmetros de construtor chamados ‘child:’ e ‘onPressed:’
O "child:" é usado para adicionar um texto :
"Clique", enquanto "onPressed:" é chamado
toda vez que o usuário pressiona o botão, sendo usado para acionar a ação
desejada.
Para simplificar, vamos apenas imprimir uma mensagem na janela do
console quando o usuário pressionar o botão.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title : Icon(Icons.home),
backgroundColor: Colors.orange
),
body:Text("Flutter - Scaffold"),
floatingActionButton: FloatingActionButton(
child: Text("Clique"),
onPressed: () {
print("O botão foi pressionado");
}
),
)
);
}
}
|
Na figura a seguir temos o texto sendo exibido no console ao clicar o botão:
Embora possamos exibir textos no botão, é uma prática geral usar ícones/imagens, por dois motivos:
Por exemplo, para adicionar um ícone, podemos simplesmente alterar "child:" assim:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title : Icon(Icons.home),
backgroundColor: Colors.orange
),
body:Text("Flutter - Scaffold"),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.Add_a_photo),
onPressed: () {
print("O botão foi pressionado");
}
),
)
);
}
}
|
3- Bottom Navigation Bar
Como o nome
sugere, a barra de navegação inferior, assim como o AppBar, é uma faixa
horizontal na parte inferior da tela. Pode ter vários itens e pode usar rótulos
de texto, ícones ou uma combinação de ambos.
A barra de navegação inferior geralmente é criada para exibir mensagens, bem
como para fornecer ações de atalho específicas da página.
Podemos criar um Bottom Navigation bar a partir do
widget "BottomNavigationBar", no entanto, com
"Scaffold" e "FloatingActionButton",
usamos o widget "BottomAppBar" porque ele fornece o
espaço para o botão de ação flutuante e não o sobrepõe.
Veja como podemos criar uma barra de navegação inferior com "BottomAppBar":
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Icon(Icons.home),
backgroundColor: Colors.orange),
body: Text("Flutter - Scaffold"),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add_a_photo),
onPressed: () {
print("O botão foi pressionado");
}),
bottomNavigationBar: BottomAppBar(
child: Text("Meu bottomNavigationBar"),
color: Colors.lime,
),
));
}
|
Como você pode
ver na figura acima, ela não se sobrepõe ao botão de ação flutuante.
Para exibir vários widgets dentro de "BottomAppBar()",
precisamos usar um contêner de widgets, como "Row()",
que podem encapsular vários widgets filhos dentro dele. Veja como fica:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Icon(Icons.home),
backgroundColor: Colors.orange),
body: Text("Flutter - Scaffold"),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add_a_photo),
onPressed: () {
print("O botão foi pressionado");
}),
bottomNavigationBar: BottomAppBar(
child: Row(
children: <Widget>[
Text("bottomNavigationBar 1 "),
Text("bottomNavigationBar 2"),
],
),
color: Colors.lime,
),
));
}
}
|
Podemos combinar texto e ícones onde os ícones podem ser apenas de exibição estática ou um botão com ações associadas.
Vamos ver um exemplo de como podemos criar os dois: texto e ícone. Novamente, para simplificar, estamos apenas imprimindo uma declaração na janela do console quando o botão do ícone for pressionado:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Icon(Icons.home),
backgroundColor: Colors.orange),
body: Text("Flutter - Scaffold"),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add_a_photo),
onPressed: () {
print("O botão foi pressionado");
}),
bottomNavigationBar: BottomAppBar(
child: Row(
children: <Widget>[
Text("bottomNavigationBar 1 "),
Icon(Icons.home),
IconButton(
icon: Icon(Icons.add_alert),
onPressed: () {
print("O IconButton foi pressionado");
}
,)
],
),
color: Colors.lime,
),
));
}
}
|
Por padrão, a barra de navegação inferior ocupa uma quantidade mínima de espaço na parte inferior da tela. No entanto, se seu aplicativo precisar, você pode aumentar o tamanho da barra de navegação inferior agrupando o child no widget 'Container()' e especificando o parâmetro height como é mostrado a seguir:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Icon(Icons.home),
backgroundColor: Colors.orange),
body: Text("Flutter - Scaffold"),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add_a_photo),
onPressed: () {
print("O botão foi pressionado");
}),
bottomNavigationBar: BottomAppBar(
child: Container(
height: 100.0,
child: Row(
children: <Widget>[
Text("bottomNavigationBar 1 "),
Icon(Icons.home),
IconButton(
icon: Icon(Icons.add_alert),
onPressed: () {
print("O IconButton foi pressionado");
},
)
],
),
),
color: Colors.lime,
),
));
}
}
|
Note que mesmo aumentando o tamanho do bottom navigation bar ele não sobrepõe o floating action bar.
4- Persistente Footer Buttons
O
Persistente Footer Button (Botão de rodapé
persistente) exibe um conjnto de
botões que permanecem persistentes na tela, mesmo que o corpo do
Scaffold role.
Se usada junto com a barra de navegação inferior, ela é exibida acima dela, mas
abaixo do body.
Também podemos usar os botões planos(Flat Buttons)
aqui, mas, para simplificar, usaremos o widget "IconButton()"
sem a função "onPressed:".
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Icon(Icons.home),
backgroundColor: Colors.orange),
body: Text("Flutter - Scaffold"),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add_a_photo),
onPressed: () {
print("O botão foi pressionado");
}),
bottomNavigationBar: BottomAppBar(
child: Container(
height: 100.0,
child: Row(
children: <Widget>[
Text("bottomNavigationBar 1 "),
Icon(Icons.home),
IconButton(
icon: Icon(Icons.add_alert),
onPressed: () {
print("O IconButton foi pressionado");
},
)
],
),
),
color: Colors.lime,
),
persistentFooterButtons: <Widget>[
IconButton (icon: Icon(Icons.access_time),onPressed: null,),
IconButton (icon: Icon(Icons.account_balance),onPressed: null,),
],
));
}
}
|
Você já percebeu que o Botão de rodapé persistente usa um array de widgets e não tem propriedades associadas a eles, como background, color, height, etc.
Ele compartilha a cor de fundo com a cor de fundo do body Scaffold. Então se eu mudar a cor de fundo do Scaffold isso vai se refletir no Botão de rodapé. Veja:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Icon(Icons.home),
backgroundColor: Colors.orange),
body: Text("Flutter - Scaffold"),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add_a_photo),
onPressed: () {
print("O botão foi pressionado");
}),
bottomNavigationBar: BottomAppBar(
child: Container(
height: 100.0,
child: Row(
children: <Widget>[
Text("bottomNavigationBar 1 "),
Icon(Icons.home),
IconButton(
icon: Icon(Icons.add_alert),
onPressed: () {
print("O IconButton foi pressionado");
},
)
],
),
),
color: Colors.lime,
),
persistentFooterButtons: <Widget>[
IconButton (icon: Icon(Icons.access_time),onPressed: null,),
IconButton (icon: Icon(Icons.account_balance),
onPressed: null,),
],
backgroundColor : Colors.pink,
));
}
}
|
4- Drawer - Navigation drawer
Para concluir vou mostrar a opção drawer do Scaffold que permite criar um navigation drawer.
No exemplo abaixo estou usando a opção drawer e incluindo um Contâiner com a cor red:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor : Colors.blue
),
home : Scaffold(
appBar: AppBar(
title: Text("Ola Flutter"),
),
body : Container (
color: Colors.orange,
),
drawer: Container(
color: Colors.red,
)
)
);
}
}
|
Para criar um menu navigation com opções basta definir um Drawer e seu filho como um ListView com uma lista de filhos ListTile onde definimos o texto e o ícone:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primaryColor: Colors.blue),
home: Scaffold(
appBar: AppBar(
title: Text("Ola Flutter"),
),
body: Container(
color: Colors.orange,
),
drawer: Drawer(
child: ListView(
children: <Widget>[
ListTile(
title: Text("Item 1"),
trailing: Icon(Icons.arrow_forward),
),
ListTile(
title: Text("Item 2"),
trailing: Icon(Icons.arrow_forward),
),
],
),
),
));
}
}
|
E temos assim um resumo da utilização do widget Scaffold e dos seus principais parâmetros.
Na próxima parte do artigo veremos como criar uma aplicação simples usando os recurso do Scaffold.
Salmos 111:2
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET
Flutter - Apresentando o widget MaterialApp - Macoratti
Flutter - Apresentando Flutter Studio - Macoratti
Flutter - Lista Básica - Macoratti
Flutter - Apresentando Widgets - Macoratti
Flutter - Obtendo dados da Web - Macoratti