Flutter é um kit de desenvolvimento, de código aberto, criado pelo Google, que permite a criação de aplicativos compilados nativamente para Android e IOS. Você escreve um único código e o aplicativo roda em ambas plataformas.
A linguagem de programação utilizada no Flutter é o Dart, uma linguagem de script voltada à web desenvolvida pela Google.
Para mais informações sobre o Dart acesse: Referência Dart
Documentação oficial: https://flutter.dev/docs
A boa notícia é que você não precisa instalar nada para rodar HTML, ele já roda no seu browser, seja ele Chrome, Firefox, Edge, Safari ou similares.
Guia de instalação no windows: https://flutter.dev/docs/get-started/install/windows
1- Instalar o Android Studio
2- Baixar o zip do Flutter e descompactar Baixar o zip no site: https://flutter.dev/docs/get-started/install/windows e descompactar o pacote em uma pasta do seu computador, por exemplo: C:\flutter Não é recomendado instalar em uma pasta com privilégios elevados, como c:\Program files
3- Adicionar o caminho do flutter e do Android Studio no path
4- Instalar o Android Command Line
Abra o Android Studio, e na página Welcome, clique em “More Actions” e então em “SDK Manager”
Na aba “SDK Tools” marcar a opção: [x] Android SDK Command-line Tools e clicar no botão Aplicar
5- Aceitar as licenças do Android
Execute o comando:
$ flutter doctor --android-licenses
6- Executar o Flutter doctor
$ flutter doctor
Se houverem pendências de instalação, elas serão listadas. Se tudo estiver ok será exibido algo como:
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.5.3, on Microsoft Windows [Version 10.0.22000.348], locale pt-BR)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[√] Android Studio (version 2020.3)
[√] VS Code (version 1.62.3)
[√] Connected device (2 available)
• No issues found!
7- Configure um emulador do Android
Abra o Android Studio, e na página Welcome, clique em “More Actions” e então em “AVD Manager”
Então escolha a opção: Create Virtual Device…
Uma ótima IDE para escrever aplicativos Flutter é o VSCode.
O VSCode é um editor FREE, rápido, leve e com uma infinidade de extensões para diferentes linguagens de programação, o que faz com que ele seja uma ótima opção para diferentes usos, vale destacar também que ele ganhou com folga a primeira posição da pesquisa anual do Stack Overflow de 2021 (link) como a IDE mais utilizada por programadores.
https://code.visualstudio.com/download
https://flutter.dev/docs/get-started/editor?tab=vscode
Dicas:
CTRL+SHIFT+P / “Dart: Use Recommended Settings”
CTRL+SHIFT+P / “Preferences: Open Workspace Settings (JSON)”
{
"dart.lineLength": 100
}
CTRL+SHIFT+P / “Preferences: Open Settings (JSON)”
alterar “editor.rulers” e incluir “editor.codeActionsOnSave”
"[dart]": {
"editor.formatOnSave": true,
"editor.formatOnType": true,
"editor.rulers": [
100
],
"editor.selectionHighlight": false,
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.suggestSelection": "first",
"editor.tabCompletion": "onlySnippets",
"editor.wordBasedSuggestions": false,
"editor.codeActionsOnSave": {
"source.fixAll": true
}
},
Vá no Android Studio e inicie o emulador (Menu: Tools / AVD Manager / Create Virtual Device…)
Abra um prompt de comando e navegue até a pasta onde deseja criar o seu app, por exemplo:
mkdir c:\dev
cd c:\dev
Para criar o app, execute:
$ flutter create helloapp
$ cd helloapp
NOTA: Na primeira vez que você criar um app irá demorar mais, porque os pacotes serão baixados, nos próximos apps o processo será mais rápido
Então, para abrir o VSCode na pasta atual, execute:
$ code .
Quando o editor for carregado, será perguntado se você confia na origem do código, clique no botão “Yes, I trust”
Abra o arquivo “main.dart” na pasta “lib”, então substitua o conteúdo dele por:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Hello App')
),
body: Text('Hello World!')
)
);
}
}
Inicie o emulador do Android (Android Studio > AVD)
então inicie a aplicação no VSCode utilizando o menu: Run / Start Debugging, ou pressionando F5.
É possível executar a aplicação utilizando o terminal também, assim:
Abra um terminal no VSCode, menu: Terminal > New Terminal E então execute:
$ flutter run
Depois que a aplicação for iniciada, digite “r” para iniciar o “Hot reload”, assim, a cada modificação realizada o aplicativo será automaticamente atualizado.
A linguagem utilizada no Flutter é o Dart.
Para informações sobre a linguagem consulte: Referência Dart
//TODO: Complementar
O jeito mais fácil de adicionar um package é executando o comando “dart pub add [package]” ele vai automaticamente adicionar no arquivo “pubspec.yaml” a referência para o pacote
Por exemplo executando:
$ dart pub add json_serializable
No arquivo “pubspec.yaml” será adicionado:
dependencies:
json_serializable: ^6.0.0
Para incluir essa pacote manualmente é necessário:
1- Adicionar a dependência no arquivo “pubspec.yaml”, por exemplo:
dependencies:
json_serializable: ^6.0.0
2- Atualizar o aplicativo com os pacotes adicionados, executando:
$ flutter pub get
Para atualizar a versão de todos os pacotes, execute:
$ flutter packages upgrade
Se houverem packages que não foi possível atualizar será exibido um erro como:
x package is discontinued.
x packages have newer versions incompatible with dependency constraints.
Para verificar os pacotes com problemas de atualização, execute:
$ flutter pub outdated
Referência: https://flutter.dev/docs/development/data-and-backend/json
O Flutter não possui equivalente ao Json.Net ou Newntonsoft do .NET para serialização e deserialização JSON porque para construir algo do tipo é necessário utilizar Reflection, que não está disponível no Flutter.
Sem a utilização de Reflection, existem duas forma de serialização no Flutter:
1- Manualmente
Na serialização manual é necessário mapear cada campo do json para um campo da classe, por exemplo:
class Album {
final int id;
final String title;
Album({
required this.id,
required this.title,
});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
id: json['id'],
title: json['title'],
);
}
}
string json = "{\"id\":1, \"title\":"Metallica Black album"}"
Map<String, dynamic> jsonMap = jsonDecode(json);
Album album = Album.fromJson(jsonMap);
Isso funciona para projetos pequenos, mas será bem difícil fazer isso manualmente para projetos grandes sem cometer erros.
2- Usando um gerador de código (recomendado)
A lib json_serializable é um exemplo de lib que faz a geração de código automaticamente
Referência oficial: https://pub.dev/packages/json_serializable
Para instalar, utilize:
$ dart pub add json_serializable
Se não tiver essas dependências, também é necessário adicionar:
$ dart pub add build_runner --dev
$ dart pub add json_annotation
A classe que será serializada (album.dart) fica assim:
import 'package:json_annotation/json_annotation.dart';
part 'album.g.dart';
class Album {
final int id;
final String title;
Album({
required this.id,
required this.title,
});
factory UserApi.fromJson(Map<String, dynamic> json) => _$AlbumFromJson(json);
Map<String, dynamic> toJson() => _$AlbumFromJson(this);
}
Para gerar os arquivos, execute:
$ flutter pub run build_runner build
Na classe (album.dart) é referenciado um arquivo parcial (part ‘album.g.dart’) esse arquivo será gerado automaticamente, quando o comando “build_runner build” for executado. Nesse arquivo estará implementado o método: _$AlbumFromJson com o mapeamento dos campos do JSON para os campos da classe.
Se ocorrer o seguinte erro:
pub finished with exit code 78
tente rodar:
$ flutter packages pub run build_runner build --delete-conflicting-outputs
O método toJson() retorna um tipo Map<String, dynamic> para converter esse mapa em uma string JSON utilize:
var album = Album(1, '');
String json = jsonEncode(album.toJson());
Documentação oficial https://pub.dev/packages/flutter_native_splash
Vídeo, como utilizar: https://www.youtube.com/watch?v=8ME8Czqc-Oc
Para instalar o pacote, execute:
$ flutter pub add flutter_native_splash
e então adicione as configurações no arquivo “pubspec.yaml”, por exemplo:
flutter_native_splash:
color: "#ffffff"
image: assets/meu-logo.png
android: true
ios: true
Depois execute:
$ flutter clean; flutter pub get; flutter pub run flutter_native_splash:create
NOTA: No Linux ou no MAC o comando é assim:
$ flutter clean && flutter pub get && flutter pub run flutter_native_splash:create
ou você pode rodar cada comando indidivualmente.
Documentação oficial: https://pub.dev/packages/flutter_launcher_icons
Para instalar o pacote, execute:
$ flutter pub add flutter_launcher_icons
No arquivo pubspec.yaml adicione:
dev_dependencies:
flutter_launcher_icons: "^0.9.2"
flutter_icons:
android: "launcher_icon"
ios: true
image_path: "assets/icon/icon.png"
Em “image_path” informar o caminho para a imagem que deve ser utilizada como ícone do app
Então execute:
flutter pub get
flutter pub run flutter_launcher_icons:main
Referência: https://flutter.dev/docs/cookbook/networking/fetch-data
Para instalar o pacote HTTP execute:
$ flutter pub add http
Isso irá adicionar a dependência abaixo no arquivo pubspec.yaml:
dependencies:
http: ^0.13.4
No código adicionar o import:
import 'package:http/http.dart' as http;
Referência https://pub.dev/packages/package_info_plus
Para instalar o pacote execute:
$ flutter pub add package_info_plus
Utilização:
import 'package:package_info_plus/package_info_plus.dart';
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String appName = packageInfo.appName;
String packageName = packageInfo.packageName;
String version = packageInfo.version;
String buildNumber = packageInfo.buildNumber;
NOTA: O número da versão do app, fica na variável “version” do arquivo pubspec.yaml
Referência: https://pub.dev/packages/logger
Para instalar o pacote execute:
$ flutter pub add logger
Utilização:
var logger = Logger();
logger.d("Log esta funcionando!");
Log levels:
logger.v("Verbose log");
logger.d("Debug log");
logger.i("Info log");
logger.w("Warning log");
logger.e("Error log");
logger.wtf("What a terrible failure log");
Uma boa opção é utilizar o plugin **cached_network_image**
Página oficial do plugin:
<a href="https://pub.dev/packages/cached_network_image" target="_blank" rel="nofollow">https://pub.dev/packages/cached_network_image</a>
Adicionar o plugin:
flutter pub add cached_network_image
Importar no widget:
import 'package:cached_network_image/cached_network_image.dart';
Exemplos de uso:
CachedNetworkImage(
imageUrl: 'https://picsum.photos/id/474/200/200',
)
CachedNetworkImage(
imageUrl: 'https://picsum.photos/id/474/200/200',
width: 200.0,
height: 200.0,
httpHeaders: {'authorization': 'bearer xxxxxx'},
)
O pacote url_launcher permite abrir uma url usando o navegador do celular
https://pub.dev/packages/url_launcher
Instalar o pacote:
$ flutter pub add url_launcher
No widget importar:
import 'package:url_launcher/url_launcher.dart';
Adicionar a entrada abaixo no arquivo AndroidManifest.xml (dentro do nó: manifest > application > activity):
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent-filter>
Ela configura o Android para aceitar a abertura de urls https, se for utilizar outro tipo de url, como e-mail, é necessário adicionar outra entrada. Para mais detalhes consulte a documentação do package: https://pub.dev/packages/url_launcher
E utilizar:
_launchURL() async {
const url = 'https://flutter.io';
if (!await launch(_url)) {
throw 'Could not launch $_url';
}
}
Documentação oficial: https://firebase.flutter.dev/docs/overview
Tutorial: https://firebase.google.com/codelabs/firebase-get-to-know-flutter
Tutorial Flutter - Configuração do Firebase: https://firebase.flutter.dev/docs/overview/
Tutorial Flutter - Firebase Messaging: https://firebase.flutter.dev/docs/messaging/overview
Projeto do Firebase
Primeiramente, crie um projeto do Firebase, para isso, acesse: https://console.firebase.google.com/
Instalar o Node.js
Se não tiver o NodeJs instalado, baixar e instalar: https://nodejs.org/en/download/
Para confirmar a instalação, abra um novo prompt de comando e digite:
node --version
Instalar do Firebase CLI
As instruções de instalação do Firebase CLI estão em: https://firebase.google.com/docs/cli
O jeito mais fácil de instalar é usando o npm, digite o seguinte no prompt:
npm install -g firebase-tools
Executar login no Firebase CLI
Ainda no prompt de comando, execute:
firebase login
Será aberto o browser para você realizar o login na sua conta do Firebase.
Você pode listar os projetos utilizando:
firebase projects:list
Instalação do plugin
Para instalar o plugin, navegue até a pasta do projeto, por exemplo:
cd c:\projetos\meu-app
e então execute o comando para instalar o plugin:
flutter pub add firebase_core
E então o comando:
dart pub global activate flutterfire_cli
Pode ser que esse comando solicite que você inclua uma variável de ambiente no windows, se for o caso, será exibida a seguinte mensagem:
Warning: Pub installs executables into C:\Users\educo\AppData\Local\Pub\Cache\bin, which is not on your path.
You can fix that by adding that directory to your system's "Path" environment variable.
A web search for "configure windows path" will show you how.
Nesse caso, inclua esse caminho no PATH do Windows. (Iniciar / Environment variables / [Environment Variables…] / System variable / PATH / [Edit] / [NEW]) Então, feche o prompt e abra outro para que o comando path esteja disponível
Para verificar a instalação execute:
flutterfire --version
Configuração do plugin
Para configurar o plugin execute:
flutterfire configure
Será pedido para selecionar o nome do projeto (usando as setas para cima e para baixo do teclado), selecione o nome do projeto criado no firebase console e pressione ENTER. Será perguntado o nome do package do seu projeto, utilize o mesmo informado no arquivo: \src\android\app\src\main\AndroidManifest.xml, é algo como: com.nomeempresa.nomeapp
Inicializar no arquivo main
Abra o arquivo lib/main.dart e adicione, os imports:
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
E adicione o código abaixo no bloco Main:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
Para receber notificações utilizando o Firebase no Flutter, primeiro siga as instruções do tópico anterior, para configurar o Firebase no seu projeto Flutter.
Instalar os pacotes:
flutter pub add firebase_messaging
flutter pub add flutter_local_notifications
Documentação oficial:
Tem um exemplo de implementação aqui:
E outro exemplo aqui:
Para o IOS, adicionar no arquivo: AppDelegate.swift o seguinte:
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
fica assim:
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
No arquivo /src/main/AndroidManifest.xml, adicionar:
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
A implementação no HomeWidget fica assim:
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print('Handling a background message: ${message.messageId}');
}
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final RefreshController _refreshController = RefreshController(initialRefresh: false);
final CustomLogger _customLogger = Get.find<CustomLogger>();
@override
void initState() {
super.initState();
// Run code required to handle interacted messages in an async function
// as initState() must not be async
setupInteractedMessage();
}
// It is assumed that all messages contain a data field with the key 'type'
Future<void> setupInteractedMessage() async {
var _messagingInstance = FirebaseMessaging.instance;
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
NotificationSettings settings = await _messagingInstance.requestPermission(
alert: true,
badge: true,
provisional: false,
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
_customLogger.logInformation('User granted permission to notification');
//Message when app is in foreground
FirebaseMessaging.onMessage.listen(_handleMessage);
// Get any messages which caused the application to open from
// a terminated state.
RemoteMessage? initialMessage = await _messagingInstance.getInitialMessage();
// If the message also contains a data property with a "type" of "chat",
// navigate to a chat screen
if (initialMessage != null) {
_handleMessage(initialMessage);
}
// Also handle any interaction when the app is in the background via a
// Stream listener
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
} else {
_customLogger.logInformation('User declined or has not accepted permission to notification');
}
}
void _handleMessage(RemoteMessage message) {
//RemoteNotification? notification = message.notification;
//AndroidNotification? android = message.notification?.android;
print('messageId: ${message.messageId}, messageType: ${message.messageType}');
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(message.notification!.title ?? 'Notificação'),
content: Text(message.notification!.body!),
actions: [
TextButton(
child: const Text("Ok"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Notificação'),
brightness: Brightness.dark,
),
body: Text('Teste'))
}
}
No IOS, ao publicar o app para a Apple Store, pode ser que você receba por e-mail o erro: “ITMS-90078: Missing Push Notification Entitlement”. Para contornar esse problema, abra o XCode e siga as instruções descritas aqui: https://stackoverflow.com/a/67074537/618464
Primeiro siga as instruções do tópico acima de configuração do Firebase no flutter, depois instale o pacote:
$ flutter pub add firebase_analytics
Documentação do pacote: https://firebase.flutter.dev/docs/analytics/overview
Primeiro siga as instruções do tópico acima de configuração do Firebase no flutter, depois instale o pacote:
$ flutter pub add firebase_crashlytics
Documentação do pacote: https://firebase.flutter.dev/docs/crashlytics/overview/
Uma opção para leitura de QR Code é o package QR Code Scanner
Documentação oficial: https://pub.dev/packages/qr_code_scanner
Instalar o plugin:
$ flutter pub add qr_code_scanner
Para utilização no IOS, adicione as linhas abaixo no arquivo Info.plist:
<key>io.flutter.embedded_views_preview</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan QR codes</string>
No arquivo app/src/main/AndroidManifest.xml adicione:
<uses-permission android:name="android.permission.CAMERA" />
Exemplo de implementação:
https://pub.dev/packages/permission_handler/example
Para utilizar a câmera é necessário verificar a permissão, utilize o package permission_handler e faça o seguinte:
Future<PermissionStatus> _getCameraPermission() async {
var permissionStatus = await Permission.camera.status;
if (!permissionStatus.isGranted) {
permissionStatus = await Permission.camera.request();
}
return permissionStatus;
}
Somente quando tiver a permissão exiba o controle.
Se tentar utilizar a câmera sem permissão ocorrerá a exception:
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: PlatformException(error, java.lang.IllegalStateException: Trying to create a platform view of unregistered type: net.touchcapture.qr.flutterqr/qrview
Pare toda a aplicação e inicie ela novamente. Se ocorrer erro da versão do Kotlin, atualize o arquivo: android\build.gradle, a variável:
ext.kotlin_version = '1.6.10'
Referências:
Para instalar o pacote execute:
$ flutter pub add eventify
Utilização:
EventEmitter emitter = new EventEmitter(); emitter.on(“test”, null, (ev, context) { print(“${ev.eventName} - ${ev.eventData}”); });
emitter.emit(“test”, null, “Test data”);
reference: https://api.flutter.dev/flutter/material/RefreshIndicator-class.html
Future _onRefresh() async {
//TODO: Executar atualizaçlão dos dados
}
Scaffold(
body: RefreshIndicator(
onRefresh: _onRefresh,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Container(
margin: const EdgeInsets.all(20.0),
child: //.. body content
),
),
),
);
NOTA: Se o conteúdo da tela não tiver um scroll maior que o tamanho da tela é é preciso utilizar: physics: const AlwaysScrollableScrollPhysics() para forçar que sempre ocorra a possibilidade do scroll
https://medium.com/@filipvk/creating-a-custom-color-swatch-in-flutter-554bcdcb27f3
@override Widget build(BuildContext context) { return MaterialApp( title: ‘Flutter Demo’, theme: ThemeData( primarySwatch: createMaterialColor(const Color(0xFF757575)), ), home: const MyHomePage(title: ‘Flutter Demo Home Page’), ); }
MaterialColor createMaterialColor(Color color) {
List strengths =
for (int i = 1; i < 10; i++) {
strengths.add(0.1 * i);
}
strengths.forEach((strength) {
final double ds = 0.5 - strength;
swatch[(strength * 1000).round()] = Color.fromRGBO(
r + ((ds < 0 ? r : (255 - r)) * ds).round(),
g + ((ds < 0 ? g : (255 - g)) * ds).round(),
b + ((ds < 0 ? b : (255 - b)) * ds).round(),
1,
);
});
return MaterialColor(color.value, swatch); }
Recomendo o seguinte vídeo que explica muito bem esses conceitos: https://www.youtube.com/watch?v=4KBqWANDbE4&t=1780s
Abaixo alguns exemplos de Widgets e propriedades que eles aceitam
Text('Seu texto aqui')
Text('Seu texto aqui', style: Theme.of(context).textTheme.headline6)
Text('Seu texto aqui', style: const TextStyle(fontWeight: FontWeight.bold))
Text('Seu texto aqui', style: TextStyle(fontSize: Theme.of(context).textTheme.bodyText2!.fontSize, color: Colors.grey.shade600))
Column(
children: [
Text('Text 1'),
Text('Text 2'),
Text('Text 3'),
],
)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Text 1'),
Text('Text 2'),
Text('Text 3'),
],
)
Row(
children: [
Text('Text 1'),
Text('Text 2'),
Text('Text 3'),
],
)
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
Text('hi'),
Text('hi'),
Text('hi'),
]
)
)
Container(
width: double.infinity,
height: 100,
constraints: const BoxConstraints(maxHeight: 200),
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 10),
child: [Widget]
)
//Container com borda arredondada:
Container(
margin: const EdgeInsets.only(left: 10),
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 5),
decoration: BoxDecoration(
color: Colors.red.shade300,
borderRadius: const BorderRadius.all(
Radius.circular(8.0),
),
),
child: const Text('Seu texto aqui', style: TextStyle(color: Colors.white)),
)
ListView(
children: <Widget>[
ListTile(
title: Text('Valor', style: Theme.of(context).textTheme.headline6),
subtitle: const Text('Título'),
)
]
)
ListView.builder(
shrinkWrap: true,
physics: const ScrollPhysics(),
itemCount: myItems.length,
itemBuilder: (context, i) {
return ListTile(
title: Text(
myItems[i].title,
style: Theme.of(context).textTheme.bodyText1,
),
subtitle: Text(
myItems[i].text,
style: Theme.of(context).textTheme.bodyText2,
),
onTap: () { /* Execute action */ },
);
}
)
ListView.separated(
shrinkWrap: true,
physics: const ScrollPhysics(),
itemCount: myItems.length,
itemBuilder: (context, i) {
return ListTile(
title: Text(
myItems[i].title,
style: Theme.of(context).textTheme.bodyText1,
),
subtitle: Text(
myItems[i].text,
style: Theme.of(context).textTheme.bodyText2,
),
onTap: () { /* Execute action */ },
);
},
separatorBuilder: (_, index) => const SizedBox(height: 5, child: Divider())),
)
Diferentes botões do Material design: https://docs.flutter.dev/development/ui/widgets/material#Buttons
ElevatedButton - botão com elevação:
ElevatedButton(
child: const Text('SIGN IN'),
onPressed: () {
controller.signInClick();
}),
TextButton - texto simples clicável:
TextButton(
child: const Text('CRIAR CONTA'),
onPressed: () { })
Outlined Button - TextButton com borda:
OutlinedButton(
child: const Text('Click Me'),
onPressed: () {
debugPrint('Received click');
},
)
adicionando ícone:
OutlinedButton(
child: const Icon(Icons.arrow_right_sharp),
onPressed: () { }
)
Icon(Icons.person, size: 30.0, color: Colors.grey.shade400),
Tem a lista de ícones na página: https://api.flutter.dev/flutter/material/Icons-class.html
Para exibir uma imagem adicionada no projeto:
1- Incluir a imagem na pasta assets 2- Se você criou uma subpasta, por exemplo “assets\icons” ou “assets\images” adicionar essa nova pasta no arquivo pubspec.yam, ou então especificar o nome dos arquivos:
flutter:
uses-material-design: true
assets:
- assets/images/
- assets/icons/
3- Utilizar na aplicação:
Image.asset('assets/icons/excel-icon-32x32.png')
(ver package: cached_network_image abaixo)
SizedBox(
width: double.infinity,
child: Wrap(
spacing: 6.0,
children: taskDetail.taskData.tags
.map((e) => Chip(
label: Text(
e.tagTitle,
)))
.toList(),
),
)
Exibição de Dialog (um modal).
Opções:
Exemplo:
showMyDialog(BuildContext context) {
var dialog = AlertDialog(
title: const Text('Título'),
content: const Text('Minha mensagem'),
actions: [
TextButton(
child: const Text('Cancelar'),
onPressed: () {},
),
TextButton(
child: const Text('Confirmar'),
onPressed: () {},
),
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return dialog;
},
);
}