Flutter: do zero a
publicação
Cícero Duarte / Cinthia Galvão
Cícero Duarte
linkedin.com/in/ciceroduarte
github.com/ciceroduarte
Desenvolvedor iOS
Cinthia Galvão
linkedin.com/in/cinthiagalvao
github.com/cpgalvao
Desenvolvedora Android
Agenda
- Flutter
- Visão geral
- Demo
- Integração com código nativo
- Geração de versão
- Case UOL VivaBem
- Prós / Contras
Motivação
- Oportunidade
- Flutter
- Possível case Google/IO
- App publicado até final de abril
O que é Flutter?
- SDK de desenvolvimento multiplataforma
- Criado pelo Google
- Desempenho
- UI rica e nativa
- Desenvolvimento rápido
- 11/05/2017: Primeira release 0.0.6
- 20/06/2018: Release Preview 1
Instalação
- Entrar em: https://flutter.io/get-started/install/
- Extrair em um diretório e adicionar ao $PATH
$ export PATH=`pwd`/flutter/bin:$PATH
$ flutter doctor
Atualização
$ flutter upgrade
Arquitetura em camadas
Engine (C++) Skia Dart Text
Framework (Dart)
Animation Painting Gestures
Foundation
Rendering
Widgets
Material Cupertino
Dart
- Apresentada pelo Google em 2011
- Substituir o Javascript
- VM ou compilada para Javascript
- Utilizada em produtos internos no Google
Flutter + Dart
- Orientada a objetos
- Opcionalmente tipada
- Declarativa
- StyleGuide bem definido
- Compila para ARM Code
- Ahead-of-time
- Just-in-time
+ =
Ahead-of-time
Just-in-time
🤖
Widgets
Container Column Row Stack Center Padding
Appbar FloatingActionButton TabBar BottomNavigationBar TextField SimpleDialog
StatefulWidgetStatelessWidget
Widget
AssetImage Text Scrollable Animatable
Widgets
Stateless - Imutável,
desenhada apenas uma vez
Stateful - Mutável, método
setState redesenha a widget
AboutPage DetailPage
Construindo um layout
Demo
Internacionalização
dependencies:
flutter_localizations:
sdk: flutter
intl:
intl_translation:
localizationsDelegates: [
// ... app-specific localization delegate[s] here
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'),
const Locale('pt', 'BR'),
// ... other locales the app supports
],
Importar dependências no pubspec.yaml
Implementar delegates e locales
class DemoLocalizations {
static Future<DemoLocalizations> load(Locale locale) {
final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
final String localeName = Intl.canonicalizedLocale(name);
return initializeMessages(localeName).then((Null _) {
Intl.defaultLocale = localeName;
return DemoLocalizations();
});
}
static DemoLocalizations of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations);
}
String get title {
return Intl.message(
'Hello World',
name: 'title',
desc: 'Title for the Demo application',
);
}
}
Implementar classe para Localization e Strings internacionalizadas
Executar comandos
$ flutter pub pub run
intl_translation:extract_to_arb
—output-dir=lib/i18n lib/main.dart$ flutter pub pub run
intl_translation:generate_from_arb
--output-dir=lib/i18n
--no-use-deferred-loading
lib/main.dart lib/i18n/intl_messages.arb
appBar: AppBar(
title: Text("Comprar"),
)
Internacionalização 🚀
dependencies:
flutter_localizations:
sdk: flutter
intl:
intl_translation:
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
S.delegate,
],
supportedLocales: S.delegate.supportedLocales,
Utilizar o plugin para extrair strings
Demo
MethodChannel
FlutterMethodChannel
MethodChannel
Integração com código nativo
Flutter
State
iOS
AppDelegate
iOS platform
APIs
3rd-Party
APIs for iOS
FlutterViewController
Android
Activity
Android
platform APIs
3rd-Party
APIs for
Android
FlutterView
Integração com código nativo
static const platform = const MethodChannel(‘tdc_demo_channel');
final String result = await platform.invokeMethod('getNativeText', param);
nativeText = 'Texto final recebido do Nativo: $result';
val channel = MethodChannel(flutterView, "tdc_demo_channel")
channel.setMethodCallHandler { call, result ->
if (call.method == "getNativeText") {
var resultString = getString(R.string.platform_string)
result.success("$resultString ${call.arguments}")
} else {
result.notImplemented()
}
}
let channel = FlutterMethodChannel(name: “tdc_demo_channel”, binaryMessenger: controller)
channel.setMethodCallHandler { (call, result) in
if call.method == "getNativeText" {
let resultString = "Método iOS, parâmetro: (call.arguments ?? "")"
result(resultString + "($0 ?? "")")
} else {
result(FlutterMethodNotImplemented)
}
}
Integração com código nativo
static const platform = const MethodChannel(‘tdc_demo_channel');
final String result = await platform.invokeMethod('getNativeText', param);
nativeText = 'Texto final recebido do Nativo: $result';
val channel = MethodChannel(flutterView, "tdc_demo_channel")
channel.setMethodCallHandler { call, result ->
if (call.method == "getNativeText") {
var resultString = getString(R.string.platform_string)
result.success("$resultString ${call.arguments}")
} else {
result.notImplemented()
}
}
let channel = FlutterMethodChannel(name: “tdc_demo_channel”, binaryMessenger: controller)
channel.setMethodCallHandler { (call, result) in
if call.method == "getNativeText" {
let resultString = "Método iOS, parâmetro: (call.arguments ?? "")"
result(resultString + "($0 ?? "")")
} else {
result(FlutterMethodNotImplemented)
}
}
Integração com código nativo
static const platform = const MethodChannel(‘tdc_demo_channel');
final String result = await platform.invokeMethod('getNativeText', param);
nativeText = 'Texto final recebido do Nativo: $result';
val channel = MethodChannel(flutterView, "tdc_demo_channel")
channel.setMethodCallHandler { call, result ->
if (call.method == "getNativeText") {
var resultString = getString(R.string.platform_string)
result.success("$resultString ${call.arguments}")
} else {
result.notImplemented()
}
}
let channel = FlutterMethodChannel(name: “tdc_demo_channel”, binaryMessenger: controller)
channel.setMethodCallHandler { (call, result) in
if call.method == "getNativeText" {
let resultString = "Método iOS, parâmetro: (call.arguments ?? "")"
result(resultString + "($0 ?? "")")
} else {
result(FlutterMethodNotImplemented)
}
}
NativePageState() {
platform.setMethodCallHandler(_handlerNativeCall);
}
Future<dynamic> _handlerNativeCall(MethodCall call) async {
switch (call.method) {
case "getFlutterText":
return Future.value("Método Flutter, parâmetro: ${call.arguments}");
}
}
channel.invokeMethod("getFlutterText", arguments: "iOSParam", result: {
print(resultString + "($0 ?? "")")
})
channel.invokeMethod(“getFlutterText", “AndroidParam”, object : MethodChannel.Result {
override fun success(p0: Any?) {
resultString = "$resultString $p0"
print(resultString)
}
override fun error(p0: String?, p1: String?, p2: Any?) { }
override fun notImplemented() { }
})
Integração com código nativo
NativePageState() {
platform.setMethodCallHandler(_handlerNativeCall);
}
Future<dynamic> _handlerNativeCall(MethodCall call) async {
switch (call.method) {
case "getFlutterText":
return Future.value("Método Flutter, parâmetro: ${call.arguments}");
}
}
channel.invokeMethod("getFlutterText", arguments: "iOSParam", result: {
print(resultString + "($0 ?? "")")
})
channel.invokeMethod(“getFlutterText", “AndroidParam”, object : MethodChannel.Result {
override fun success(p0: Any?) {
resultString = "$resultString $p0"
print(resultString)
}
override fun error(p0: String?, p1: String?, p2: Any?) { }
override fun notImplemented() { }
})
Integração com código nativo
NativePageState() {
platform.setMethodCallHandler(_handlerNativeCall);
}
Future<dynamic> _handlerNativeCall(MethodCall call) async {
switch (call.method) {
case "getFlutterText":
return Future.value("Método Flutter, parâmetro: ${call.arguments}");
}
}
channel.invokeMethod("getFlutterText", arguments: "iOSParam", result: {
print(resultString + "($0 ?? "")")
})
channel.invokeMethod(“getFlutterText", “AndroidParam”, object : MethodChannel.Result {
override fun success(p0: Any?) {
resultString = "$resultString $p0"
print(resultString)
}
override fun error(p0: String?, p1: String?, p2: Any?) { }
override fun notImplemented() { }
})
Integração com código nativo
Gerando versão Android
$ flutter clean
$ flutter build apk --release
$ zipalign -v -p 4
app-release.apk app-release-final.apk
$ apksigner sign --ks <my-release-key.jks>
--out app-release-final-assinada.apk
app-release-final.apk
$ apksigner verify --print-certs
app-release-final-assinada.apk
Gerando versão iOS
$ flutter clean
$ flutter build ios --release
$ open ios/Runner.xcworkspace
Case
- VivaBem
- Canal de saúde e bem-estar do UOL
- Aplicativo
- Meditação e mindfulness
- Notícias e blogs
- Lembretes
- Aplicativo atraente
- Componentes de UI
- Animações
- Funcionalidades do app
- Reprodução de áudio
- Google Analytics
- Notificações
Case
16/02
20/02
28/02
26/03
23/04
03/05
Proposta do case
Início de POCs
POCs -> início
do projeto
Publicação nas lojas
Android e iOS.
Reunião com cliente
sobre app
Versão release
candidate
Confirmação
SandBox area
no Google I/O
Case
Case
Prós Contras
- Desempenho
- Hot reload
- Integração com código nativo
- Integridade dos layouts
- Webview/Maps
- Integração com views nativas
- Falta de componentes nativos
- Suporte para devices 32bits
- Suporte para Android SDK16+
Links
- Flutter
- https://flutter.io/
- Instalação/Update do ambiente
- https://flutter.io/get-started/install/
- https://flutter.io/upgrading/
- Widgets
- https://flutter.io/tutorials/layout/
- https://flutter.io/widgets/
- Internacionalização
- https://flutter.io/tutorials/internationalization/
- Integração com código nativo
- https://flutter.io/platform-channels/
- Showcase
- https://flutter.io/showcase/
Cícero Duarte
linkedin.com/in/ciceroduarte
Cinthia Galvão
linkedin.com/in/cinthiagalvao
https://github.com/cpgalvao/tdc_demo

Mais conteúdo relacionado

PDF
Desenvolvendo Apps Nativos com Flutter
PDF
Flutter do zero a publicacao
PPTX
O que há de incrível sobre o Flutter
PPTX
Introdução básica ao JavaScript
PPSX
Android - Programação para dispositivos móveis (Aula 1)
PPTX
Introduction à React
PDF
clean code
PPTX
Introduction to DDD
Desenvolvendo Apps Nativos com Flutter
Flutter do zero a publicacao
O que há de incrível sobre o Flutter
Introdução básica ao JavaScript
Android - Programação para dispositivos móveis (Aula 1)
Introduction à React
clean code
Introduction to DDD

Mais procurados (20)

PDF
Mobile DevOps pipeline using Google Flutter
PPTX
PDF
Introdução ao JavaScript
PPTX
Mono Repo
PDF
Aprendendo a Usar o Netbeans
PPTX
2 introdução c sharp
PDF
Flutter
PPTX
Flutter for tche linux
PDF
Presentation du socle technique Java open source Scub Foundation
DOCX
Full stack Java Developer
PDF
(Declarative) Jenkins Pipelines
PPT
CI and CD with Jenkins
PPTX
Dart presentation
PDF
Domain Driven Design
PDF
Clean Code na Prática
PDF
Intro To React Native
PDF
Introduction a Flutter
PDF
PDF
Understanding redux
PDF
Arquitectura hexagonal
Mobile DevOps pipeline using Google Flutter
Introdução ao JavaScript
Mono Repo
Aprendendo a Usar o Netbeans
2 introdução c sharp
Flutter
Flutter for tche linux
Presentation du socle technique Java open source Scub Foundation
Full stack Java Developer
(Declarative) Jenkins Pipelines
CI and CD with Jenkins
Dart presentation
Domain Driven Design
Clean Code na Prática
Intro To React Native
Introduction a Flutter
Understanding redux
Arquitectura hexagonal
Anúncio

Semelhante a Flutter do zero a publicacao (20)

PDF
TDC2018SP | Trilha Mobile - Flutter: do zero a publicacao
PDF
Flutter do zero a publicacao
PDF
Java orientação a objetos (interfaces)
KEY
Python 08
PDF
Golang para desenvolvedores pragmáticos parte 2
PDF
Android na Prática
PDF
Geolocalização em PHP - Google Places, Maps e Routes
PPT
Compus Party - processing e arduino
PPTX
Curso de Introdução ao Android Básico
PDF
Ecosistema spring a_plataforma_enterprise_jav
PDF
Python: Cabe no seu bolso, no seu micro, no seu cérebro.
PPTX
TDC 2015 - Execução em Background e Live Tiles em Universal Apps
PDF
PyData - Consumindo e publicando web APIs com Python
PDF
Integração do Flex com PHP através do AMFPHP
PDF
Mini Curso PHP Twig - PHP Conference 2017
PDF
O que esperar do Zend Framework 3
PPT
Mock Objects
PPTX
C#4 - Parte 2 - COM interop e variância
PDF
Código legado - PHP Conference Brasil - 2014
PDF
Evento Front End SP - Organizando o Javascript
TDC2018SP | Trilha Mobile - Flutter: do zero a publicacao
Flutter do zero a publicacao
Java orientação a objetos (interfaces)
Python 08
Golang para desenvolvedores pragmáticos parte 2
Android na Prática
Geolocalização em PHP - Google Places, Maps e Routes
Compus Party - processing e arduino
Curso de Introdução ao Android Básico
Ecosistema spring a_plataforma_enterprise_jav
Python: Cabe no seu bolso, no seu micro, no seu cérebro.
TDC 2015 - Execução em Background e Live Tiles em Universal Apps
PyData - Consumindo e publicando web APIs com Python
Integração do Flex com PHP através do AMFPHP
Mini Curso PHP Twig - PHP Conference 2017
O que esperar do Zend Framework 3
Mock Objects
C#4 - Parte 2 - COM interop e variância
Código legado - PHP Conference Brasil - 2014
Evento Front End SP - Organizando o Javascript
Anúncio

Último (12)

PPT
10_ slides de Reuso sommerville cap 10.ppt
PDF
SLIDES - AULA 7 - SWING - Cleyton Souza - IFPB
PDF
SLIDES - AULA 1 - APRESENTAÇÃO - Material de Cleyton Souza - IFPB
PPT
03_slide de Gerenciamento de Projetos .ppt
PDF
SLIDES - AULA 5 - HERANÇA - Material de Cleyton Souza - IFPB
PPT
07_slides de Estilos_Arquiteturais sommerville.ppt
PPT
06_slide de Arquitetura_de_Software .ppt
PDF
SLIDES - AULA 3 - CLASSES E OBJETOS EM JAVA - Material de Cleyton Souza - IFPB
PPT
05_slide especificacao de sistemas de software e a uml UML.ppt
PDF
SLIDES - AULA 2 - INTRODUÇÃO - Material de Cleyton Souza - IFPB
PPT
00_Apresentacao sobre o livro do sommerville_ES.ppt
PPT
09_Evolucao de software e_Refatoracao.ppt
10_ slides de Reuso sommerville cap 10.ppt
SLIDES - AULA 7 - SWING - Cleyton Souza - IFPB
SLIDES - AULA 1 - APRESENTAÇÃO - Material de Cleyton Souza - IFPB
03_slide de Gerenciamento de Projetos .ppt
SLIDES - AULA 5 - HERANÇA - Material de Cleyton Souza - IFPB
07_slides de Estilos_Arquiteturais sommerville.ppt
06_slide de Arquitetura_de_Software .ppt
SLIDES - AULA 3 - CLASSES E OBJETOS EM JAVA - Material de Cleyton Souza - IFPB
05_slide especificacao de sistemas de software e a uml UML.ppt
SLIDES - AULA 2 - INTRODUÇÃO - Material de Cleyton Souza - IFPB
00_Apresentacao sobre o livro do sommerville_ES.ppt
09_Evolucao de software e_Refatoracao.ppt

Flutter do zero a publicacao

  • 1. Flutter: do zero a publicação Cícero Duarte / Cinthia Galvão
  • 2. Cícero Duarte linkedin.com/in/ciceroduarte github.com/ciceroduarte Desenvolvedor iOS Cinthia Galvão linkedin.com/in/cinthiagalvao github.com/cpgalvao Desenvolvedora Android
  • 3. Agenda - Flutter - Visão geral - Demo - Integração com código nativo - Geração de versão - Case UOL VivaBem - Prós / Contras
  • 4. Motivação - Oportunidade - Flutter - Possível case Google/IO - App publicado até final de abril
  • 5. O que é Flutter? - SDK de desenvolvimento multiplataforma - Criado pelo Google - Desempenho - UI rica e nativa - Desenvolvimento rápido - 11/05/2017: Primeira release 0.0.6 - 20/06/2018: Release Preview 1
  • 6. Instalação - Entrar em: https://flutter.io/get-started/install/ - Extrair em um diretório e adicionar ao $PATH $ export PATH=`pwd`/flutter/bin:$PATH $ flutter doctor
  • 8. Arquitetura em camadas Engine (C++) Skia Dart Text Framework (Dart) Animation Painting Gestures Foundation Rendering Widgets Material Cupertino
  • 9. Dart - Apresentada pelo Google em 2011 - Substituir o Javascript - VM ou compilada para Javascript - Utilizada em produtos internos no Google
  • 10. Flutter + Dart - Orientada a objetos - Opcionalmente tipada - Declarativa - StyleGuide bem definido - Compila para ARM Code - Ahead-of-time - Just-in-time + =
  • 13. Widgets Container Column Row Stack Center Padding Appbar FloatingActionButton TabBar BottomNavigationBar TextField SimpleDialog
  • 14. StatefulWidgetStatelessWidget Widget AssetImage Text Scrollable Animatable Widgets Stateless - Imutável, desenhada apenas uma vez Stateful - Mutável, método setState redesenha a widget AboutPage DetailPage
  • 16. Demo
  • 17. Internacionalização dependencies: flutter_localizations: sdk: flutter intl: intl_translation: localizationsDelegates: [ // ... app-specific localization delegate[s] here GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], supportedLocales: [ const Locale('en', 'US'), const Locale('pt', 'BR'), // ... other locales the app supports ], Importar dependências no pubspec.yaml Implementar delegates e locales
  • 18. class DemoLocalizations { static Future<DemoLocalizations> load(Locale locale) { final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString(); final String localeName = Intl.canonicalizedLocale(name); return initializeMessages(localeName).then((Null _) { Intl.defaultLocale = localeName; return DemoLocalizations(); }); } static DemoLocalizations of(BuildContext context) { return Localizations.of<DemoLocalizations>(context, DemoLocalizations); } String get title { return Intl.message( 'Hello World', name: 'title', desc: 'Title for the Demo application', ); } } Implementar classe para Localization e Strings internacionalizadas
  • 19. Executar comandos $ flutter pub pub run intl_translation:extract_to_arb —output-dir=lib/i18n lib/main.dart$ flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/i18n --no-use-deferred-loading lib/main.dart lib/i18n/intl_messages.arb
  • 20. appBar: AppBar( title: Text("Comprar"), ) Internacionalização 🚀 dependencies: flutter_localizations: sdk: flutter intl: intl_translation: localizationsDelegates: [ GlobalMaterialLocalizations.delegate, S.delegate, ], supportedLocales: S.delegate.supportedLocales, Utilizar o plugin para extrair strings
  • 21. Demo
  • 22. MethodChannel FlutterMethodChannel MethodChannel Integração com código nativo Flutter State iOS AppDelegate iOS platform APIs 3rd-Party APIs for iOS FlutterViewController Android Activity Android platform APIs 3rd-Party APIs for Android FlutterView
  • 23. Integração com código nativo static const platform = const MethodChannel(‘tdc_demo_channel'); final String result = await platform.invokeMethod('getNativeText', param); nativeText = 'Texto final recebido do Nativo: $result'; val channel = MethodChannel(flutterView, "tdc_demo_channel") channel.setMethodCallHandler { call, result -> if (call.method == "getNativeText") { var resultString = getString(R.string.platform_string) result.success("$resultString ${call.arguments}") } else { result.notImplemented() } } let channel = FlutterMethodChannel(name: “tdc_demo_channel”, binaryMessenger: controller) channel.setMethodCallHandler { (call, result) in if call.method == "getNativeText" { let resultString = "Método iOS, parâmetro: (call.arguments ?? "")" result(resultString + "($0 ?? "")") } else { result(FlutterMethodNotImplemented) } }
  • 24. Integração com código nativo static const platform = const MethodChannel(‘tdc_demo_channel'); final String result = await platform.invokeMethod('getNativeText', param); nativeText = 'Texto final recebido do Nativo: $result'; val channel = MethodChannel(flutterView, "tdc_demo_channel") channel.setMethodCallHandler { call, result -> if (call.method == "getNativeText") { var resultString = getString(R.string.platform_string) result.success("$resultString ${call.arguments}") } else { result.notImplemented() } } let channel = FlutterMethodChannel(name: “tdc_demo_channel”, binaryMessenger: controller) channel.setMethodCallHandler { (call, result) in if call.method == "getNativeText" { let resultString = "Método iOS, parâmetro: (call.arguments ?? "")" result(resultString + "($0 ?? "")") } else { result(FlutterMethodNotImplemented) } }
  • 25. Integração com código nativo static const platform = const MethodChannel(‘tdc_demo_channel'); final String result = await platform.invokeMethod('getNativeText', param); nativeText = 'Texto final recebido do Nativo: $result'; val channel = MethodChannel(flutterView, "tdc_demo_channel") channel.setMethodCallHandler { call, result -> if (call.method == "getNativeText") { var resultString = getString(R.string.platform_string) result.success("$resultString ${call.arguments}") } else { result.notImplemented() } } let channel = FlutterMethodChannel(name: “tdc_demo_channel”, binaryMessenger: controller) channel.setMethodCallHandler { (call, result) in if call.method == "getNativeText" { let resultString = "Método iOS, parâmetro: (call.arguments ?? "")" result(resultString + "($0 ?? "")") } else { result(FlutterMethodNotImplemented) } }
  • 26. NativePageState() { platform.setMethodCallHandler(_handlerNativeCall); } Future<dynamic> _handlerNativeCall(MethodCall call) async { switch (call.method) { case "getFlutterText": return Future.value("Método Flutter, parâmetro: ${call.arguments}"); } } channel.invokeMethod("getFlutterText", arguments: "iOSParam", result: { print(resultString + "($0 ?? "")") }) channel.invokeMethod(“getFlutterText", “AndroidParam”, object : MethodChannel.Result { override fun success(p0: Any?) { resultString = "$resultString $p0" print(resultString) } override fun error(p0: String?, p1: String?, p2: Any?) { } override fun notImplemented() { } }) Integração com código nativo
  • 27. NativePageState() { platform.setMethodCallHandler(_handlerNativeCall); } Future<dynamic> _handlerNativeCall(MethodCall call) async { switch (call.method) { case "getFlutterText": return Future.value("Método Flutter, parâmetro: ${call.arguments}"); } } channel.invokeMethod("getFlutterText", arguments: "iOSParam", result: { print(resultString + "($0 ?? "")") }) channel.invokeMethod(“getFlutterText", “AndroidParam”, object : MethodChannel.Result { override fun success(p0: Any?) { resultString = "$resultString $p0" print(resultString) } override fun error(p0: String?, p1: String?, p2: Any?) { } override fun notImplemented() { } }) Integração com código nativo
  • 28. NativePageState() { platform.setMethodCallHandler(_handlerNativeCall); } Future<dynamic> _handlerNativeCall(MethodCall call) async { switch (call.method) { case "getFlutterText": return Future.value("Método Flutter, parâmetro: ${call.arguments}"); } } channel.invokeMethod("getFlutterText", arguments: "iOSParam", result: { print(resultString + "($0 ?? "")") }) channel.invokeMethod(“getFlutterText", “AndroidParam”, object : MethodChannel.Result { override fun success(p0: Any?) { resultString = "$resultString $p0" print(resultString) } override fun error(p0: String?, p1: String?, p2: Any?) { } override fun notImplemented() { } }) Integração com código nativo
  • 29. Gerando versão Android $ flutter clean $ flutter build apk --release $ zipalign -v -p 4 app-release.apk app-release-final.apk $ apksigner sign --ks <my-release-key.jks> --out app-release-final-assinada.apk app-release-final.apk $ apksigner verify --print-certs app-release-final-assinada.apk
  • 30. Gerando versão iOS $ flutter clean $ flutter build ios --release $ open ios/Runner.xcworkspace
  • 31. Case - VivaBem - Canal de saúde e bem-estar do UOL - Aplicativo - Meditação e mindfulness - Notícias e blogs - Lembretes
  • 32. - Aplicativo atraente - Componentes de UI - Animações - Funcionalidades do app - Reprodução de áudio - Google Analytics - Notificações Case
  • 33. 16/02 20/02 28/02 26/03 23/04 03/05 Proposta do case Início de POCs POCs -> início do projeto Publicação nas lojas Android e iOS. Reunião com cliente sobre app Versão release candidate Confirmação SandBox area no Google I/O Case
  • 34. Case
  • 35. Prós Contras - Desempenho - Hot reload - Integração com código nativo - Integridade dos layouts - Webview/Maps - Integração com views nativas - Falta de componentes nativos - Suporte para devices 32bits - Suporte para Android SDK16+
  • 36. Links - Flutter - https://flutter.io/ - Instalação/Update do ambiente - https://flutter.io/get-started/install/ - https://flutter.io/upgrading/ - Widgets - https://flutter.io/tutorials/layout/ - https://flutter.io/widgets/ - Internacionalização - https://flutter.io/tutorials/internationalization/ - Integração com código nativo - https://flutter.io/platform-channels/ - Showcase - https://flutter.io/showcase/

Notas do Editor

  • #4: [Cinthia] Vamos falar de Flutter, uma visão geral, vamos fazer uma demo, mostrar integração com código Android e iOS, como gerar uma versão para publicar. Também iremos mostrar nosso case que foi destaque no Google I/O, e fechar com prós e contras do Flutter
  • #5: [Cinthia] O que nos levou a descobrir o Flutter? No início do ano, recebemos uma oportunidade/desafio de desenvolver um app em Flutter e esse app tinha chances de ser um case no Google I/O se fosse publicado até o final de abril
  • #6: [Cinthia] O que é Flutter? É um SDK para desenvolvimento de aplicativos multiplataforma, que foi criado pelo Google e tem como princípios: desempenho, o app desenvolvido tem performance de app nativo; UI rica e nativa, com experiência do usuário natural de cada plataforma; e desenvolvimento rápido, através do uso de widgets e do hot reload. A primeira versão do flutter foi lançada há pouco mais de 1 ano e atualmente está na versão Release Preview 1.
  • #7: [Cícero] Para iniciar o desenvolvimento em Flutter, é necessário baixar a SDK, extrair o conteúdo do zip e adicionar o diretório onde foi extraído o flutter, no path. A partir daí, pode ser feito um flutter doctor em um terminal para validar a instalação. Pode ser utilizado o Android Studio ou o IntelliJ, adicionando os plugins do Flutter e do Dart, ou ainda o Visual Studio Code com a extension do Flutter.
  • #8: [Cícero] Para atualizar a versão do Flutter, que está em constante desenvolvimento, basta executar flutter upgrade. Há também outros 2 comandos que serão bastante utilizados: packages get e packages upgrade. Cada vez que o arquivo pubspec.yaml for alterado, adicionando ou alterando um pacote, será necessário executá-los.
  • #9: [Cícero] // Falar em camadas O Flutter essencialmente é organizado em camadas, podemos separar em duas camadas principais, a Engine e o Framework. A Engine é a camada escrita em C/C++ que compõe a estrutura de execução, tendo a Skia, uma biblioteca de renderização 2D e de texto, que também é utilizada por exemplo no Google Chrome e no próprio Android e além da Skia, tem o Dart, que é a linguagem que utilizamos para desenvolver em Flutter. A camada verde é o Framework, é a parte totalmente escrita em Dart, ou seja, tudo que você utiliza na ferramenta é escrito em Dart, ela controla toda a parte de renderização, gestures, animações e possui o principal pilar do Flutter, as Widgets. // Falar sobre framework reativo moderno; // APIs de teste Tudo no Flutter são Widgets, não só componentes visuais como TextFields e Labels, Widgets também são utilizadas para estruturar o layout, como as Widgets de Center, Row e Column. Acima das Widgets podemos ver na mesma camada os itens Material e Cupertino, que são os conjuntos de Widgets específicas para Android e iOS, logicamente Material são as de Android e Cupertino as de iOS
  • #10: [Cícero] Uma das dúvidas mais frequentes sobre o Flutter é: Por que utilizar Dart e não Kotlin, Swift ou Javascript? Para responder essa pergunta temos que analisar as características do Flutter e um pouco da estratégia do Google com relação ao Dart. Eu particularmente nunca tinha ouvido falar em Dart até conhecer o Flutter, então de onde saiu? Apresentada pelo Google a primeira vez em 2011; Objetivo de substituir o Javascript como principal linguagem embutida nos navegadores; Inicialmente podia rodar em uma VM ou compilada para Javascript; Atualmente é utilizada em vários produtos internos no google.
  • #11: [Cícero] O Dart não é a primeira linguagem padrão para desenvolver em Flutter, inicialmente era desenvolvido em Javascript, mas a ideia do time de desenvolvimento do Flutter era criar a melhor maneira de desenvolver para mobile, e utilizando Javascript complicaria a maneira que eles queriam gerar os binários para publicação. Com isso, começaram a buscar e analisar várias linguagem existentes no mercado e a que teve uma maior pontuação geral foi o Dart, mas pq? É orientada a objetos É declarativa, fazendo com que os layouts sejam montados de maneira parecida com CSS É uma linguagem majoritariamente mantida pelo Google Pode ser tipada Curva de aprendizagem Tem um StyleGuide bem definido Compila para ARM Code E o mais importante quesito que torna o Dart essencial para o Flutter é que ele pode ser compilado tanto em Ahead-of-time e como Just-in-time, mas o que é isso?
  • #12: [Cícero] O código da aplicação é compilado direto para código ARM nativo, o que possibilita que a aplicação seja inicializadas com performance de uma aplicação nativa.
  • #13: [Cícero] Com o objetivo de ser a melhor maneira de desenvolver para mobile, um dos principais feedback que o time do Flutter teve foi que um dos pontos que poderiam melhorar era a velocidade do próprio ciclo de desenvolvimento. A maneira mais comum que desenvolvemos é: Escrevemos código, mandamos rodar e esperamos até que o código seja compilado, o pacote seja gerando, instalado no device e no pior dos casos temos que percorrer várias telas até chegar onde acabamos de fazer a alteração, para ver se deu certo. Um dos objetivos do Flutter é cortar esse tempo de espera, é aí que a compilação Just-in-time do Dart cai como uma luva no Flutter, com ela podemos compilar diretamente no device com a aplicação em execução e ver em praticamente tempo real se a alteração deu certo ou não.
  • #14: [Cícero] // Apresentar na prática, mostrando exemplos de uso e falando sobre os benefícios: Como as Widgets são renderizadas na camada do Flutter, ela apresentam o mesmo layout independente da versão do Android ou iOS, ou seja, você terá um layout moderno em devices antigos sem ter que fazer manobras e nem perder performance. Widgets não são compostas com herança, mas sim com composição.
  • #15: [Cinthia] As Widgets são divididas em 2 grandes grupos, o primeiro são as Stateless, que são widgets imutáveis, desenhadas apenas uma vez, como exemplo delas temos os labels de texto, imagens, e no nosso código de exemplo, a AboutPage. As outras são as Stateful, que são mutáveis, onde o método setState redesenha a widget. Os exemplos são views Scrollable, Animadas e a DetailPage do nosso código de exemplo.
  • #16: [Cinthia] Como eu começo construir um layout? A Scaffold Widget permite que itens básicos sejam adicionados na tela, como AppBar, FloatingActionButton, BottomNavigationBar, Drawer, além do conteúdo da tela. Alguns itens de tela, são facilitados, como a ListView, onde cada item pode ser um ListTile, e só é preciso setar o título, o subtítulo e a imagem dos itens, o layout é montado nesse formato.
  • #17: [Cinthia] Agora vamos ver como ajustar um layout. Este é nosso app, ele mostra uma lista de frutas, e quando clicamos em um item, vemos os detalhes de uma fruta. - temos um layout com a imagem da fruta, nome, preço e quantidade, porém, está ruim assim... então vamos centralizar esses itens (Center), verticalmente também (MainAxisAlignment.center). Salvamos e pronto. Este é o hot-reload, que assim que salvamos, atualiza o app no emulador ou no device. - podemos aumentar o texto da imagem da fruta (tst) - podemos aumentar também a fonte do nome da fruta (tst) - a fonte do preço, vamos também deixar negrito (tst). - podemos também colocar um padding para não ficar tão próximo (Padding) - e não é só layout que podemos mudar e ver o resultado imediatamente, vamos alterar nosso FloatingButton, que ao invés de adicionar um item, vamos remover um item (Icon.remove / count--)
  • #18: [Cinthia] Para internacionalizar Strings em dart/flutter, devemos importar as dependências de internacionalização no yaml, implementar os delegates e locales na classe do application
  • #19: [Cinthia] Implementar uma classe para a Localization e descrição de cada uma das Strings internacionalizadas
  • #20: [Cinthia] E por último, executar os 2 comandos: extract_to_arb, que irá gerar o arquivo arb com as Strings extraídas da classe, onde será possível traduzí-las, e depois o generate_from_arb que irá processar as strings traduzidas.
  • #21: [Cinthia] Porém, temos uma maneira mais simples e fácil, que é utilizando o plugin Flutter i18n, onde é necessário importar as dependências de internacionalização no yaml, implementar os delegates e locales na classe do app, e extrair e traduzir as Strings utilizando o plugin
  • #22: [Cícero] Vamos internacionalizar o título da tela de Comprar, então, basta selecionarmos a opção de extrair a string, selecionar a linguagem, e definir um id para essa string. Depois basta fazer este mesmo processo para as demais linguas, ou editar diretamente os arquivos arb
  • #23: [Cinthia] É possível integrar o código do Flutter ao nativo, que para Android pode ser em Java ou Kotlin, e para iOS pode ser em objective-C ou Swift. Para fazer a integração deve ser utilizado um canal, que pode ser utilizado em ambos os sentidos: para o flutter acessar o código nativo ou para o código nativo acessar o flutter.
  • #24: [Cinthia] Aqui vemos um exemplo do código Flutter acessando código nativo
  • #25: primeiramente criamos o channel, que neste caso se chama tdc_demo_channel, e então fazemos um invokeMethod, utilizando esse channel e passando por parâmetro do método invokeMethod, o nome do método nativo e os parâmetros que desejamos enviar ao nativo.
  • #26: Do lado do nativo, tanto para Android, quanto para iOS, também precisamos criar o channel, com o mesmo nome, e implementar o método setMethodCallHandler, onde iremos validar o conteúdo do método, e então implementar o seu conteúdo. No nosso caso, retornamos uma string, com o valor “Método Android ou iOS” e apendamos a essa string, os parâmetros recebidos do flutter. Por fim, enviamos através do result o resultado do método nativo executado.
  • #27: [Cícero] Aqui vemos um exemplo do código nativo acessando código flutter.
  • #28: Da mesma maneira que o sentido inverso, devemos criar o canal, e apenas inverter o que vimos anteriormente: o código nativo chama o método Flutter através do invokeMethod, passando o nome do método Flutter a ser chamado e os parâmetros a serem enviados para esse método. E então implementamos a callback para receber o resultado do método de flutter que foi chamado.
  • #29: Do lado do flutter, implementamos o setMethodCallHandler para receber o chamado do código nativo, e validar o nome do método, e então implementamos o conteúdo do método, retornando o resultado. Neste caso o retorno seria a string “Método flutter, parâmetro” e os parâmetros recebidos do código nativo.
  • #30: [Cinthia] Para gerar a versão final do app Android, basta executar o comando flutter build apk release, passar o zipalign, e assinar o apk. A partir daí, é só subir na loja o apk.
  • #31: [Cícero] Para gerar a versão de iOS, utilizamos o comando flutter build ios release, e abrimos o arquivo do workspace, e então, através do xcode, podemos submeter a versão para a app store
  • #32: [Cícero] Agora vamos falar sobre o app que nos levou a aprender Flutter! Viva bem é o canal de saúde e bem-estar do UOL. E o objetivo era fazer um aplicativo contendo práticas de meditação e mindfulness, notícias e blogs da área, além de lembretes através de notificações para lembrar o usuário de praticar a meditação
  • #33: [Cícero] No VivaBem, nosso foco foi utilizar diversos componentes de UI e trabalhar com animações para gerar um aplicativo atraente. E com reprodução de áudio, utilização do google analytics e push notifications para atender os requisitos do app.
  • #34: [Cinthia] Assim que recebemos a proposta do case e começamos o estudo de Flutter através do desenvolvimento de POCs, de diversos componentes de UI, requests, parser de jsons. Durante os estudos, tivemos uma reunião com o cliente sobre o app e na semana seguinte, iniciamos o projeto. Em 1 mês finalizamos a versão Beta do app e depois de mais 1 mês, quando ficamos aguardando os áudios das meditações e fazendo ajustes no app, publicamos o app nas lojas. E no começo de maio, veio a confirmação que o VivaBem havia sido aprovado para ser um case na SandBox area do Google I/O
  • #35: [Cinthia] Aqui está um vídeo com uma demo do nosso app. Este vídeo foi utilizado na Sandbox do Flutter no Google I/O, e o app está no site do Flutter, na área de Showcase. Se quiserem baixar nosso app, está nas lojas, do Android e do iOS, e esse QRCode tem os links diretos.
  • #36: [Cícero]
  • #37: [Cícero]