Flutter já escreveu muitos artigos. Todo mês está se tornando mais popular. Por isso, decidi interpretar a documentação oficial do Flutter em um formato conciso de perguntas e respostas. Acho que muitos, como eu, não têm tempo livre suficiente para estudar em detalhes a documentação da estrutura com a qual eles ainda não funcionam.
Se você quiser entender para que serve essa estrutura e avaliar quanto esforço você precisará fazer para usá-la, seja bem-vindo ao gato.

Conteúdo:
- Visualizações
- Intenções
- Interface do usuário assíncrona
- Estrutura e Recursos do Projeto
- Atividades e Fragmentos
- Layouts
- Gestos e manipulação de eventos por toque.
- Listviews e adaptadores
- Trabalhar com texto
- Formulário de entrada
- Flutter Plugins
- Temas
- Bancos de dados e armazenamento local
- Notificações
Visualizações
Pergunta:
Qual é o equivalente de
View in Flutter?
A resposta é:
WidgetDiferenças:
Ver - de fato, o que estará na tela. Invalidate () é chamado para exibir as alterações.
Widget - uma descrição do que estará na tela. Pois a mudança é criada novamente.
Informações adicionais:
Quando lançado no próprio Android, o View está sob o capô do Widget. Flutter inclui a biblioteca de
componentes de material . Ele contém widgets que implementam as
diretrizes de design de material .
Pergunta:
Como atualizar a exibição de widgets?
A resposta é:
Usando
StatefulWidget e seu
estado . O Flutter possui 2 tipos de widgets:
StatelessWidget e
StatefulWidget . Eles funcionam da mesma maneira, a única diferença está no estado de renderização.
Diferenças:
StatelessWidget tem um estado imutável. Adequado para a exibição de texto, logotipo etc. I.e. se o elemento na tela não mudar durante todo o tempo de exibição, ele combina com você. Também pode ser usado como um contêiner para widgets com estado.
StatefulWidget possui o estado State, que armazena informações sobre o estado atual. Se você deseja alterar um elemento na tela ao executar alguma ação (uma resposta veio do servidor, o usuário clicou em um botão etc.) - esta é sua opção.
Um exemplo:
1) StatelessWidget - Texto
Text( 'I like Flutter!', style: TextStyle(fontWeight: FontWeight.bold), );
2) StatefulWidget - quando você clica no botão (FloatingActionButton), o texto no widget Texto muda de "Eu gosto de vibração" para "Flutter é impressionante!".
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Pergunta:
Como fazer o layout de uma tela com widgets? Onde está o arquivo de layout XML?
A resposta é:
O Flutter não possui layout XML para telas. Tudo digitado na árvore de widgets diretamente no código.
Um exemplo:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Sample App"), ), body: Center( child: MaterialButton( onPressed: () {}, child: Text('Hello'), padding: EdgeInsets.only(left: 10.0, right: 10.0), ), ), ); }
Todos os widgets padrão no Flutter podem ser visualizados no
catálogo de widgets .
Pergunta:
Como adicionar ou remover um componente no layout enquanto o aplicativo está em execução?
A resposta é:
Através de uma função que retornará o widget desejado, dependendo do estado.
Diferenças:
No Android, você pode addView () ou removeView () em um ViewGroup. No Flutter não é possível, porque os widgets permanecem inalterados. Somente sua condição pode mudar.
Um exemplo:
Como alterar o texto para o botão, clicando em FloatingActionButton.
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Pergunta:
Como animar widgets?
A resposta é:
Usando a classe
AnimationController , que é o descendente da classe abstrata
Animation <T> . Além de iniciar a animação, ele pode pausar, retroceder, parar e reproduzir na direção oposta. Funciona com o
Ticker , que relata um redesenho da tela.
Diferenças:
No Android, você pode criar animações em XML ou animar o View usando animate (). No Flutter, a animação deve ser escrita em código usando o AnimationController.
Informações adicionais:
Você pode aprender mais nos
widgets Animação e movimento ,
tutorial Animações e
visão geral de Animações .
Um exemplo:
Desvanece a animação do logotipo Flutter.
import 'package:flutter/material.dart'; void main() { runApp(FadeAppTest()); } class FadeAppTest extends StatelessWidget {
Pergunta:
Como usar o
Canvas ?
A resposta é:
Android e Flutter têm a mesma API para Canvas, pois eles usam o mesmo motor
Skia de baixo nível.
Diferenças:
Não.
Informações adicionais:
O Flutter possui duas classes para desenhar no Canvas -
CustomPaint e
CustomPainter . O segundo implementa seu algoritmo de renderização.
Leia mais aqui:
StackOverflowUm exemplo:
import 'package:flutter/material.dart'; void main() => runApp(MaterialApp(home: DemoApp())); class DemoApp extends StatelessWidget { Widget build(BuildContext context) => Scaffold(body: Signature()); } class Signature extends StatefulWidget { SignatureState createState() => SignatureState(); } class SignatureState extends State<Signature> { List<Offset> _points = <Offset>[]; Widget build(BuildContext context) { return GestureDetector( onPanUpdate: (DragUpdateDetails details) { setState(() { RenderBox referenceBox = context.findRenderObject(); Offset localPosition = referenceBox.globalToLocal(details.globalPosition); _points = List.from(_points)..add(localPosition); }); }, onPanEnd: (DragEndDetails details) => _points.add(null), child: CustomPaint(painter: SignaturePainter(_points), size: Size.infinite), ); } } class SignaturePainter extends CustomPainter { SignaturePainter(this.points); final List<Offset> points; void paint(Canvas canvas, Size size) { var paint = Paint() ..color = Colors.black ..strokeCap = StrokeCap.round ..strokeWidth = 5.0; for (int i = 0; i < points.length - 1; i++) { if (points[i] != null && points[i + 1] != null) canvas.drawLine(points[i], points[i + 1], paint); } } bool shouldRepaint(SignaturePainter other) => other.points != points; }
Pergunta:
Como criar widgets personalizados?
A resposta é:
Componha widgets dentro de um (em vez de herança).
Diferenças:
No Android, podemos herdar da Vista em que estamos interessados e adicionar nossa própria lógica. No Flutter, isso é semelhante a um ViewGroup, apenas o widget é sempre herdado de StatelessWidget ou StatefulWidget. I.e. você precisa criar um novo widget e usá-lo como conjunto de parâmetros ou campos.
Um exemplo:
class CustomButton extends StatelessWidget { final String label; CustomButton(this.label); @override Widget build(BuildContext context) { return RaisedButton(onPressed: () {}, child: Text(label)); } } @override Widget build(BuildContext context) { return Center( child: CustomButton("Hello"), ); }
Intenções
Pergunta:
Qual é o análogo da
Intent in Flutter?
A resposta é:
Ele não está lá. Para navegar entre as telas, as classes
Navegador e
Rota são usadas.
Para interagir com componentes externos (por exemplo, uma câmera ou seletor de arquivos), você pode usar
plug -
ins ou integração nativa em cada plataforma. Saiba mais sobre integração nativa:
desenvolvendo pacotes e plugins .
Diferenças:
Flutter não possui Atividade e Fragmento. Existem Navegador (Navegador) e Rotas (rotas). O aplicativo Flutter é semelhante a um aplicativo de atividade única, em que telas diferentes representam fragmentos diferentes e o FragmentManager os controla. O Navegador é semelhante ao FragmentManager em princípio. Pode
pressionar push () ou
pop () para a rota que você especificar. A rota é um tipo de fragmento, mas no Flutter é comum comparar com uma tela ou página.
No Android, descrevemos todas as atividades entre as quais podemos navegar no AndroidManifest.xml.
O Flutter tem duas maneiras:
- Descrever um mapa chamado Route (MaterialApp)
- Navegue diretamente para o Route (WidgetApp).
Um exemplo:
void main() { runApp(MaterialApp( home: MyAppHome(),
Pergunta:
Como processar intenções provenientes de outros aplicativos?
A resposta é:
Interagindo com a camada Android do aplicativo por meio do
MethodChannel .
Um exemplo:
Escrevemos filtro de intenção no AndroidManifest.xml:
<activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> </activity>
Processamos o Intent em MainActivity e chamamos o código do Flutter por meio do MethodChannel:
package com.example.shared; import android.content.Intent; import android.os.Bundle; import java.nio.ByteBuffer; import io.flutter.app.FlutterActivity; import io.flutter.plugin.common.ActivityLifecycleListener; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterActivity { private String sharedText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); Intent intent = getIntent(); String action = intent.getAction(); String type = intent.getType(); if (Intent.ACTION_SEND.equals(action) && type != null) { if ("text/plain".equals(type)) { handleSendText(intent);
Solicitamos dados quando o widget começa a ser desenhado:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Pergunta:
Qual é o análogo de
startActivityForResult () ?
A resposta é:
A palavra-chave wait e o resultado de uma
classe Future .
Diferenças:
Depois de chamar startActivityForResult () no Android, precisamos implementar o processamento em onActivityResult (). O Flutter não precisa implementar nada, porque O método navigator push () retorna um objeto Future.
Um exemplo:
Map coordinates = await Navigator.of(context).pushNamed('/location');
E quando tivermos as coordenadas na tela '/ location', pop ():
Navigator.of(context).pop({"lat":43.821757,"long":-79.226392});
Interface do usuário assíncrona
Pergunta:
Qual é o análogo de
runOnUiThread () no Flutter?
A resposta é:
O Dart implementa um modelo de execução de thread único que é executado no
Isolates . A execução assíncrona usa async / waitit, que você pode estar familiarizado com as rotinas C #, JavaScript ou Kotlin.
Um exemplo:
Atendendo à solicitação e retornando o resultado para atualizar a interface do usuário:
loadData() async { String dataURL = "https://jsonplaceholder.typicode.com/posts"; http.Response response = await http.get(dataURL); setState(() { widgets = json.decode(response.body); }); }
Quando a resposta à solicitação é recebida, você precisa chamar o método
setState () para redesenhar a árvore do widget com os novos dados.
Um exemplo:
Carregando e atualizando dados em um
ListView :
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Sample App', theme: ThemeData( primarySwatch: Colors.blue, ), home: SampleAppPage(), ); } } class SampleAppPage extends StatefulWidget { SampleAppPage({Key key}) : super(key: key); @override _SampleAppPageState createState() => _SampleAppPageState(); } class _SampleAppPageState extends State<SampleAppPage> { List widgets = []; @override void initState() { super.initState(); loadData(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Sample App"), ), body: ListView.builder( itemCount: widgets.length, itemBuilder: (BuildContext context, int position) { return getRow(position); })); } Widget getRow(int i) { return Padding( padding: EdgeInsets.all(10.0), child: Text("Row ${widgets[i]["title"]}") ); } loadData() async { String dataURL = "https://jsonplaceholder.typicode.com/posts"; http.Response response = await http.get(dataURL); setState(() { widgets = json.decode(response.body); }); } }
Pergunta:
Como executar código em um thread em segundo plano?
A resposta é:
Como mencionado acima - usando assíncrono / espera e isolamento (Isolar).
Diferenças:
Pronto para uso no Android, você pode usar o AsyncTask. Você precisa implementar
onPreExecute () ,
doInBackground () ,
onPostExecute () nele . No Flutter "pronto para uso", você só precisa usar assíncrono / aguardar, o Dart cuidará do resto.
Um exemplo:
Aqui o método dataLoader () é isolado. Isoladamente, você pode executar operações pesadas, como analisar JSONs grandes, criptografia, processamento de imagem etc.
loadData() async { ReceivePort receivePort = ReceivePort(); await Isolate.spawn(dataLoader, receivePort.sendPort);
Pergunta:
O que é equivalente ao Flutter do
OkHttp ?
A resposta é:
O Flutter possui seu próprio
pacote HTTP .
Informações adicionais:
Até o momento, nem todos os recursos do OkHttp foram implementados no pacote HTTP; portanto, muitos dos recursos ausentes são abstraídos e você pode implementá-los, conforme necessário.
Um exemplo:
Para usar o pacote HTTP, adicione-o como uma dependência no pubspec.yaml:
dependencies: ... http: ^0.11.3+16
Para executar a solicitação, aguarde a chamada na função assíncrona http.get ():
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; [...] loadData() async { String dataURL = "https://jsonplaceholder.typicode.com/posts"; http.Response response = await http.get(dataURL); setState(() { widgets = json.decode(response.body); }); } }
Pergunta:
Como mostrar progresso?
A resposta é:
Usando o widget
ProgressIndicator .
Um exemplo:
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Sample App', theme: ThemeData( primarySwatch: Colors.blue, ), home: SampleAppPage(), ); } } class SampleAppPage extends StatefulWidget { SampleAppPage({Key key}) : super(key: key); @override _SampleAppPageState createState() => _SampleAppPageState(); } class _SampleAppPageState extends State<SampleAppPage> { List widgets = []; @override void initState() { super.initState(); loadData(); } showLoadingDialog() { return widgets.length == 0; } getBody() { if (showLoadingDialog()) { return getProgressDialog(); } else { return getListView(); } } getProgressDialog() { return Center(child: CircularProgressIndicator()); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Sample App"), ), body: getBody()); } ListView getListView() => ListView.builder( itemCount: widgets.length, itemBuilder: (BuildContext context, int position) { return getRow(position); }); Widget getRow(int i) { return Padding(padding: EdgeInsets.all(10.0), child: Text("Row ${widgets[i]["title"]}")); } loadData() async { String dataURL = "https://jsonplaceholder.typicode.com/posts"; http.Response response = await http.get(dataURL); setState(() { widgets = json.decode(response.body); }); } }
Estrutura e Recursos do Projeto
Pergunta:
Onde armazenar recursos de diferentes resoluções?
A resposta é:
Em ativos.
Diferenças:
No Android, os recursos têm uma pasta res e ativos. Flutter tem apenas ativos. A pasta de ativos pode estar localizada em qualquer lugar do projeto, principalmente, escreva o caminho para ele no arquivo pubspec.yaml.
Informações adicionais:
Comparação dos tamanhos de recursos gráficos no Android e no Flutter.
O Flutter usa o AssetManager ou classes especializadas começando com o Asset para usar os recursos no código.
Um exemplo:
AssetManager:
val flutterAssetStream = assetManager.open("flutter_assets/assets/my_flutter_asset.png")
Local do Recurso:
images/my_icon.png // Base: 1.0x image images/2.0x/my_icon.png // 2.0x image images/3.0x/my_icon.png // 3.0x image
Caminho no arquivo pubspec.yaml:
assets: - images/my_icon.jpeg
Usando
AssetImage :
return AssetImage("images/a_dot_burr.jpeg");
Usando o ativo diretamente:
@override Widget build(BuildContext context) { return Image.asset("images/my_image.png"); }
Pergunta:
Onde armazenar cordas? Como localizá-los?
A resposta é:
Armazenar em campos estáticos. Localize usando o
pacote intl .
Um exemplo:
class Strings { static String welcomeMessage = "Welcome To Flutter"; } Text(Strings.welcomeMessage)
Pergunta:
Qual é o análogo do arquivo gradle? Como adicionar dependências?
A resposta é:
pubspec.yaml.
Informações adicionais:
O Flutter delega a montagem aos construtores nativos do Android e iOS. Veja uma lista de todas as bibliotecas populares de Flutter no
Pub .
Atividades e Fragmentos
Pergunta:
Qual é o equivalente de
Atividade e
Fragmento em Flutter?
A resposta é:
Tudo no Flutter é widgets. O papel da atividade e dos fragmentos para trabalhar com a interface do usuário é desempenhado por widgets. E o papel da navegação, conforme mencionado no parágrafo sobre navegação, é Navegador e Rota.
Informações adicionais:
Flutter Para desenvolvedores do Android: como criar uma UI de atividade no Flutter .
Pergunta:
Como lidar com eventos do ciclo de vida?
A resposta é:
Usando o
método WidgetsBinding e
didChangeAppLifecycleState () .
Informações adicionais:
Flutter usa FlutterActivity no código nativo, e o mecanismo Flutter torna as alterações de estado de processamento o mais discretas possível. Mas se você ainda precisa fazer algum trabalho, dependendo do estado, o ciclo de vida é um pouco diferente:
- inativo - esse método é apenas no iOS, no Android não há analógico;
- pausado - semelhante ao onPause () no Android;
- retomado - semelhante ao onPostResume () no Android;
- suspensão - semelhante ao onStop no Android, no iOS não há analógico.
Isso é descrito em mais detalhes na
documentação do
AppLifecycleStatus .
Um exemplo:
import 'package:flutter/widgets.dart'; class LifecycleWatcher extends StatefulWidget { @override _LifecycleWatcherState createState() => _LifecycleWatcherState(); } class _LifecycleWatcherState extends State<LifecycleWatcher> with WidgetsBindingObserver { AppLifecycleState _lastLifecycleState; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override void didChangeAppLifecycleState(AppLifecycleState state) { setState(() { _lastLifecycleState = state; }); } @override Widget build(BuildContext context) { if (_lastLifecycleState == null) return Text('This widget has not observed any lifecycle changes.', textDirection: TextDirection.ltr); return Text('The most recent lifecycle state this widget observed was: $_lastLifecycleState.', textDirection: TextDirection.ltr); } } void main() { runApp(Center(child: LifecycleWatcher())); }
Layouts
Pergunta:
Qual é o análogo do
LinearLayout ?
A resposta é:
Linha para horizontal,
coluna para vertical.
Informações adicionais:
Flutter Para desenvolvedores do Android: como criar o LinearLayout no Flutter?Um exemplo:
@override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('Row One'), Text('Row Two'), Text('Row Three'), Text('Row Four'), ], ); } @override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('Column One'), Text('Column Two'), Text('Column Three'), Text('Column Four'), ], ); }
Pergunta:
Qual é o equivalente a
RelativeLayout ?
A resposta é:
Pilha de Widget.
Mais detalhes:
StackoverflowPergunta:
Qual é o análogo do
ScrollView ?
A resposta é:
ListView com widgets.
Um exemplo:
@override Widget build(BuildContext context) { return ListView( children: <Widget>[ Text('Row One'), Text('Row Two'), Text('Row Three'), Text('Row Four'), ], ); }
Pergunta:
Como lidar com transições entre retrato e paisagem?
A resposta é:
FlutterView manipula inversões se AndroidManifest.xml contiver
android: configChanges = "orientação | tamanho da tela"
Gestos e manipulação de eventos por toque
Pergunta:
Como adicionar um ouvinte onClick para widget no Flutter?
A resposta é:
Se o widget suportar cliques, em onPressed (). Caso contrário, em onTap ().
Um exemplo:
Em onPressed ():
@override Widget build(BuildContext context) { return RaisedButton( onPressed: () { print("click"); }, child: Text("Button")); }
Em onTap ():
class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: GestureDetector( child: FlutterLogo( size: 200.0, ), onTap: () { print("tap"); }, ), )); } }
Pergunta:
Como lidar com outros gestos em widgets?
A resposta é:
Usando o
GestureDetector . Eles podem lidar com as seguintes ações:
Toque
Toque duas vezes
Pressão longa
Arrasto vertical
Arrasto horizontal
Um exemplo:
Processando onDoubleTap:
AnimationController controller; CurvedAnimation curve; @override void initState() { controller = AnimationController(duration: const Duration(milliseconds: 2000), vsync: this); curve = CurvedAnimation(parent: controller, curve: Curves.easeIn); } class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: GestureDetector( child: RotationTransition( turns: curve, child: FlutterLogo( size: 200.0, )), onDoubleTap: () { if (controller.isCompleted) { controller.reverse(); } else { controller.forward(); } }, ), )); } }
Listviews e adaptadores
Pergunta:
Qual é o análogo do
ListView no Flutter?
A resposta é:
ListViewDiferenças:
O Flutter não precisa pensar em limpar e reutilizar itens (que é o que o ListView / RecyclerView faz no Android, usando o padrão ViewHolder).
Um exemplo:
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
:
?
A resposta é:
GestureDetector .
Um exemplo:
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
:
ListView ?
A resposta é:
,
setState() . ,
ListView.Builder ,
RecyclerView .
Um exemplo:
setState() :
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
ListView.Builder :
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
:
?
A resposta é:
( ) pubspec.yaml.
Um exemplo:
fonts: - family: MyCustomFont fonts: - asset: fonts/MyCustomFont.ttf - style: italic
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Sample App"), ), body: Center( child: Text( 'This is a custom font text', style: TextStyle(fontFamily: 'MyCustomFont'), ), ), ); }
:
?
A resposta é:
:
- color;
- decoration;
- decorationColor;
- decorationStyle;
- fontFamily;
- fontSize;
- fontStyle;
- fontWeight;
- hashCode;
- height;
- inherit;
- letterSpacing;
- textBaseline;
- wordSpacing.
:
Retrieve the value of a text field .
:
hint
TextInput ?
A resposta é:
InputDecoration , .
Um exemplo:
body: Center( child: TextField( decoration: InputDecoration(hintText: "This is a hint"), ) )
:
?
A resposta é:
—
InputDecoration .
Um exemplo:
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Flutter
:
GPS?
A resposta é:
geolocator .
:
?
A resposta é:
image_picker .
:
Facebook?
A resposta é:
flutter_facebook_login .
:
Firebase?
A resposta é:
Firebase
Flutter first party plugins .
:
() ?
A resposta é:
Flutter EventBus . :
developing packages and plugins .
:
NDK?
A resposta é:
NDK- Flutter. Flutter .
Themes
:
(Theme) ?
A resposta é:
MaterialApp WidgetApp .
Um exemplo:
class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Sample App', theme: ThemeData( primarySwatch: Colors.blue, textSelectionColor: Colors.red ), home: SampleAppPage(), ); } }
:
Shared Preferences?
A resposta é:
Shared_Preferences plugin ( NSUserDefaults iOS ).
Um exemplo:
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() { runApp( MaterialApp( home: Scaffold( body: Center( child: RaisedButton( onPressed: _incrementCounter, child: Text('Increment Counter'), ), ), ), ), ); } _incrementCounter() async { SharedPreferences prefs = await SharedPreferences.getInstance(); int counter = (prefs.getInt('counter') ?? 0) + 1; print('Pressed $counter times.'); prefs.setInt('counter', counter); }
:
SQLite Flutter?
A resposta é:
SQFlite .
:
push-?
A resposta é:
Firebase_Messaging .
Conclusão
. , , . « » . «-» . , ? 2016 Kotlin, - 2017. , , . , .
2016 Flutter Dart. , 2018 . . ! , , , . ( Google Fuchsia , , , Flutter ). — ! , — . Isso é tudo para mim. Google Play!