Esta é a parte final de uma interpretação concisa da documentação do Flutter que será útil para os desenvolvedores do Xamarin.Forms. Dada a situação atual, agora é a hora de aprender algo novo! De acordo com o corte, você pode encontrar informações suficientes para avaliar se vale a pena mudar de uma estrutura de plataforma cruzada para outra e quanto tempo levará. Se essas informações não forem suficientes ou você tiver experiência em desenvolvimento nativo para uma plataforma específica, recomendo procurar em outras partes:Flutter. Parte 1. Para desenvolvedores do AndroidFlutter. Parte 2. Para desenvolvedores do iOSFlutter. Parte 3. Para reagir a desenvolvedores NativeFlutter. Parte 4. Para desenvolvedores da webFlutter. Parte 5. Para desenvolvedores do Xamarin.Forms
Se essas informações não forem suficientes ou você tiver experiência em desenvolvimento nativo para uma plataforma específica, recomendo procurar em outras partes:Flutter. Parte 1. Para desenvolvedores do AndroidFlutter. Parte 2. Para desenvolvedores do iOSFlutter. Parte 3. Para reagir a desenvolvedores NativeFlutter. Parte 4. Para desenvolvedores da webFlutter. Parte 5. Para desenvolvedores do Xamarin.FormsConteúdo:
- Projeto
 
 
- Views
 
 
 
 
- Async UI
 
 
 
 
 
 
- Layouts
 
 
 
 
- ListView
 
 
- Texto
 
 
- Flutter Plugins
 
 
- Código específico da plataforma
 
 
- Depuração
 
 
- Armazenamento local
 
 
Projeto
Questão:
Onde fica o ponto de entrada?Responda:
Função main().Diferenças:
No Xamarin.Forms, é isso LoadApplication(new App());.Exemplo:
void main() {
  runApp(new MyApp());
}
Questão:
Como criar uma página ou elemento ?Responda:
O Flutter não tem conceito de página e elemento como tal. Todos os componentes são widgets. 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. Essa. 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 a classe 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.Exemplo:
StatelessWidget:class MyApp extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
StatefulWidget:class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        
        
        title: new Text(widget.title),
      ),
      body: new Center(
        
        
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }
}
Visualizações
Questão:
Como organizar widgets? Qual é o equivalente a um XAMLarquivo?Responda:
No Flutter, o layout é feito diretamente no código usando a árvore de widgets.Diferença:
No Xamarin.Forms, o layout geralmente é feito em um XAMLarquivo. Flutter não tem equivalente.Informação adicional:
A lista de widgets pode ser vista aqui .Exemplo:
@override
Widget build(BuildContext context) {
  return new Scaffold(
    appBar: new AppBar(
      title: new Text("Sample App"),
    ),
    body: new Center(
      child: new MaterialButton(
        onPressed: () {},
        child: new Text('Hello'),
        padding: new EdgeInsets.only(left: 10.0, right: 10.0),
      ),
    ),
  );
}
Questão:
Como adicionar ou remover um widget através do código?Responda:
Atualizando o estado do widget pai e reconstruindo a árvore do widget.Diferenças:
No Xamarin.Forms, isso pode ser feito usando a propriedade do Contentelemento ou métodos Add()e Remove().Exemplo:
class SampleApp extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Sample App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new SampleAppPage(),
    );
  }
}
class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);
  @override
  _SampleAppPageState createState() => new _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
  
  bool toggle = true;
  void _toggle() {
    setState(() {
      toggle = !toggle;
    });
  }
  _getToggleChild() {
    if (toggle) {
      return new Text('Toggle One');
    } else {
      return new CupertinoButton(
        onPressed: () {},
        child: new Text('Toggle Two'),
      );
    }
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Sample App"),
      ),
      body: new Center(
        child: _getToggleChild(),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _toggle,
        tooltip: 'Update Text',
        child: new Icon(Icons.update),
      ),
    );
  }
}
Questão:
Como animar um widget?Responda:
Usando os Animação e AnimationController aulas .Diferenças:
Xamarin.Forms usa ViewExtensions e métodos como FadeToou TranslateTo.Informação adicional:
Leia mais sobre animação aqui .Exemplo:
import 'package:flutter/material.dart';
void main() {
  runApp(new FadeAppTest());
}
class FadeAppTest extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Fade Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyFadeTest(title: 'Fade Demo'),
    );
  }
}
class MyFadeTest extends StatefulWidget {
  MyFadeTest({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyFadeTest createState() => new _MyFadeTest();
}
class _MyFadeTest extends State<MyFadeTest> with TickerProviderStateMixin {
  AnimationController controller;
  CurvedAnimation curve;
  @override
  void initState() {
    controller = new AnimationController(duration: const Duration(milliseconds: 2000), vsync: this);
    curve = new CurvedAnimation(parent: controller, curve: Curves.easeIn);
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
          child: new Container(
              child: new FadeTransition(
                  opacity: curve,
                  child: new FlutterLogo(
                    size: 100.0,
                  )))),
      floatingActionButton: new FloatingActionButton(
        tooltip: 'Fade',
        child: new Icon(Icons.brush),
        onPressed: () {
          controller.forward();
        },
      ),
    );
  }
}
Questão:
Como desenhar na tela?Responda:
Usando os CustomPaint e aulas CustomPainter .Diferenças:
O Xamarin.Forms usa um SkiaSharp de terceiros . No Flutter, o Skia Canvas é usado diretamente da caixa.Exemplo:
import 'package:flutter/material.dart';
void main() => runApp(new MaterialApp(home: new DemoApp()));
class DemoApp extends StatelessWidget {
  Widget build(BuildContext context) => new Scaffold(body: new Signature());
}
class Signature extends StatefulWidget {
  SignatureState createState() => new SignatureState();
}
class SignatureState extends State<Signature> {
  List<Offset> _points = <Offset>[];
  Widget build(BuildContext context) {
    return new GestureDetector(
      onPanUpdate: (DragUpdateDetails details) {
        setState(() {
          RenderBox referenceBox = context.findRenderObject();
          Offset localPosition =
          referenceBox.globalToLocal(details.globalPosition);
          _points = new List.from(_points)..add(localPosition);
        });
      },
      onPanEnd: (DragEndDetails details) => _points.add(null),
      child: new CustomPaint(painter: new SignaturePainter(_points), size: Size.infinite),
    );
  }
}
class SignaturePainter extends CustomPainter {
  SignaturePainter(this.points);
  final List<Offset> points;
  void paint(Canvas canvas, Size size) {
    var paint = new 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;
}
Questão:
Como mudar a transparência?Responda:
Usando o widget Opacity .Diferenças:
Xamarin.Forms usa a opacidade do VisualElement . No Flutter, você só precisa agrupar o widget desejado no Opacity .Questão:
Como criar widgets personalizados?Responda:
Componha-os dentro de um (em vez de herança).Diferenças:
No Xamarin.Forms, você pode herdar do VisualElement que nos interessa e adicionar sua própria lógica. No Flutter, um widget é sempre herdado de StatelessWidget e StatefulWidget . Essa. você precisa criar um novo widget e usar o conjunto de widgets necessários nele como parâmetros ou campos.Exemplo:
class CustomButton extends StatelessWidget {
  final String label;
  CustomButton(this.label);
  @override
  Widget build(BuildContext context) {
    return new RaisedButton(onPressed: () {}, child: new Text(label));
  }
}
Navegação
Questão:
Como navegar entre telas?Responda:
Para navegar entre telas, as classes Navegador e Rota são usadas .Diferenças:
Xamarin.Forms usa o NavigationPage .O Flutter possui dois métodos de navegação semelhantes ao NavigationPage :- Mapeie os nomes para descrever a rota ;
- Navegue diretamente para Rota .
O Navegador pode pressionar () ou pop () para a rota especificada.Exemplo:
void main() {
  runApp(CupertinoApp(
    home: MyAppHome(), 
    routes: <String, WidgetBuilder> {
      '/a': (BuildContext context) => MyPage(title: 'page A'),
      '/b': (BuildContext context) => MyPage(title: 'page B'),
      '/c': (BuildContext context) => MyPage(title: 'page C'),
    },
  ));
}
Navigator.of(context).pushNamed('/b');
Questão:
Como navegar para um aplicativo de terceiros?Responda:
Usando implementações nativas via MethodChannel ou plugin url_launcher .Interface do usuário assíncrona
Questão:
Qual é o equivalente de Device.BeginInvokeOnMainThread () ? Como executar código de forma assíncrona?Responda:
O Dart implementa um modelo de execução de thread único que é executado no Isolates . Para execução assíncrona, use async / waitit, que você está familiarizado com C #.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 de carregamento e atualização de 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);
    });
  }
}
Questão:
Como fazer solicitações de rede?Responda:
Usando o plugin http .Exemplo:
Conectar dependência via pubspec.yaml:dependencies:
  ...
  http: ^0.11.3+16
Inquérito: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);
    });
  }
}
Questão:
Como exibir o progresso de operações longas?Responda:
Usando ProgressIndicator .Diferenças:
No Xamarin.Forms, isso pode ser feito diretamente, colocando um indicador de progresso em XAML.Exemplo:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
  runApp(new SampleApp());
}
class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Sample App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new SampleAppPage(),
    );
  }
}
class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);
  @override
  _SampleAppPageState createState() => new _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 new Center(child: new CircularProgressIndicator());
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Sample App"),
        ),
        body: getBody());
  }
  ListView getListView() => new ListView.builder(
      itemCount: widgets.length,
      itemBuilder: (BuildContext context, int position) {
        return getRow(position);
      });
  Widget getRow(int i) {
    return new Padding(padding: new EdgeInsets.all(10.0), child: new 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
Questão:
Onde armazenar recursos de diferentes resoluções?Responda:
In assets.Diferenças:
O Xamarin.Forms não possui um armazenamento unificado para recursos da plataforma, portanto, você deve armazená-los em pastas da plataforma separadamente. Há uma vibração assets. A pasta assetspode estar localizada em qualquer lugar do projeto, e mais importante, escreva o caminho para ela no arquivo pubspec.yaml.Informação adicional:
Comparação dos tamanhos de recursos gráficos no Android e Flutter.Exemplo de layout de 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
Um exemplo de caminho em um pubspec.yamlarquivo:assets:
 - images/my_icon.jpeg
Um exemplo de uso do AssetImage :return AssetImage("images/a_dot_burr.jpeg");
Exemplo de uso direto asset:@override
Widget build(BuildContext context) {
  return Image.asset("images/my_image.png");
}
Questão:
Onde armazenar cordas? Como localizá-los?Responda:
O Flutter não tem um local específico para armazenar seqüências de caracteres no momento. Eles são propostos para serem armazenados como campos estáticos em uma classe separada. Os plug-ins são usados para localização, por exemplo, flutter_localizations ou l10n .Diferenças:
Xamarin.Forms usa um arquivo resx.Exemplo:
Armazenamento:class Strings {
  static String welcomeMessage = "Welcome To Flutter";
}
Usando:new Text(Strings.welcomeMessage)
Localização:dependencies:
  # ...
  flutter_localizations:
    sdk: flutter
  intl: "^0.15.6"
import 'package:flutter_localizations/flutter_localizations.dart';
new MaterialApp(
 localizationsDelegates: [
   
   GlobalMaterialLocalizations.delegate,
   GlobalWidgetsLocalizations.delegate,
 ],
 supportedLocales: [
    const Locale('en', 'US'), 
    const Locale('he', 'IL'), 
    
  ],
  
)
Questão:
Onde está o arquivo do projeto?Responda:
O Flutter não possui um arquivo de projeto para abrir esse projeto no ambiente de desenvolvimento. O arquivo semelhante mais próximo - pubspec.yaml- contém dependências de plugins e detalhes do projeto.Ciclo de vida do aplicativo
Questão:
Como lidar com eventos do ciclo de vida?Responda:
Usando o método WidgetsBinding e didChangeAppLifecycleState () .Informação adicional:
O Flutter usa FlutterActivity no código Android e FlutterAppDelegate no iOS; por esse motivo , 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.
Consulte a documentação do AppLifecycleStatus para obter mais detalhes .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
Questão:
Qual é o análogo do StackLayout ?Responda:
O análogo do StackLayout com orientação vertical é Column e com horizontal - Row .Exemplo:
Coluna:@override
Widget build(BuildContext context) {
  return new Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      new Text('Column One'),
      new Text('Column Two'),
      new Text('Column Three'),
      new Text('Column Four'),
    ],
  );
}
Linha:@override
Widget build(BuildContext context) {
  return new Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      new Text('Row One'),
      new Text('Row Two'),
      new Text('Row Three'),
      new Text('Row Four'),
    ],
  );
}
Questão:
Qual é o análogo da grade ?Responda:
O GridView .Exemplo:
GridView.count(
  
  
  crossAxisCount: 2,
  
  children: List.generate(100, (index) {
    return Center(
      child: Text(
        'Item $index',
        style: Theme.of(context).textTheme.headline,
      ),
    );
  }),
);
Questão:
Qual é o análogo do ScrollView ?Responda:
O analógico mais próximo é o SingleChildScrollView . Mas o Flutter costuma usar o ListView para criar conteúdo que está rastreando .Exemplo:
SingleChildScrollView:@override
Widget build(BuildContext context) {
  return new SingleChildScrollView(
    child: new Text('Long Content'),
  );
}
Exibição de lista:@override
Widget build(BuildContext context) {
  return new ListView(
    children: <Widget>[
      new Text('Row One'),
      new Text('Row Two'),
      new Text('Row Three'),
      new Text('Row Four'),
    ],
  );
}
Manuseio de gestos
Questão:
Como lidar com cliques?Responda:
Se o widget suportar o método onPressed, você poderá manipular o clique usando-o. Caso contrário, isso pode ser feito através do GestureDetector .Exemplo:
onPressed:@override
Widget build(BuildContext context) {
  return new RaisedButton(
      onPressed: () {
        print("click");
      },
      child: new Text("Button"));
}
GestureDetector:class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new Center(
      child: new GestureDetector(
        child: new FlutterLogo(
          size: 200.0,
        ),
        onTap: () {
          print("tap");
        },
      ),
    ));
  }
}
Questão:
Como lidar com gestos?Responda:
Usando o GestureDetector . Eles podem lidar com as seguintes ações:Toque
Toque duplo
Pressão longa
Arrasto vertical
Arrasto horizontal
Exemplo:
AnimationController controller;
CurvedAnimation curve;
@override
void initState() {
  controller = new AnimationController(duration: const Duration(milliseconds: 2000), vsync: this);
  curve = new CurvedAnimation(parent: controller, curve: Curves.easeIn);
}
class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new Center(
          child: new GestureDetector(
            child: new RotationTransition(
                turns: curve,
                child: new FlutterLogo(
                  size: 200.0,
                )),
            onDoubleTap: () {
              if (controller.isCompleted) {
                controller.reverse();
              } else {
                controller.forward();
              }
            },
        ),
    ));
  }
}
ListView e adaptadores
Questão:
Qual é o análogo do ListView ?Responda:
O ListView .Diferenças:
No Xamarin.Forms, você precisa criar um ViewCell e (na maioria das vezes) um DataTemplateSelector e passá-los para o ListView . No Flutter, você só precisa passar uma lista de widgets para exibir.Exemplo:
import 'package:flutter/material.dart';
void main() {
  runApp(new SampleApp());
}
class SampleApp extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Sample App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new SampleAppPage(),
    );
  }
}
class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);
  @override
  _SampleAppPageState createState() => new _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Sample App"),
      ),
      body: new ListView(children: _getListData()),
    );
  }
  _getListData() {
    List<Widget> widgets = [];
    for (int i = 0; i < 100; i++) {
      widgets.add(new Padding(padding: new EdgeInsets.all(10.0), child: new Text("Row $i")));
    }
    return widgets;
  }
}
Questão:
Como determinar em qual elemento foi clicado?Responda:
No Flutter, um widget de elemento deve manipular seu próprio clique.Diferenças:
O Xamarin.Forms costuma usar o ItemTapped .Exemplo:
import 'package:flutter/material.dart';
void main() {
  runApp(new SampleApp());
}
class SampleApp extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Sample App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new SampleAppPage(),
    );
  }
}
class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);
  @override
  _SampleAppPageState createState() => new _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Sample App"),
      ),
      body: new ListView(children: _getListData()),
    );
  }
  _getListData() {
    List<Widget> widgets = [];
    for (int i = 0; i < 100; i++) {
      widgets.add(new GestureDetector(
        child: new Padding(
            padding: new EdgeInsets.all(10.0),
            child: new Text("Row $i")),
        onTap: () {
          print('row tapped');
        },
      ));
    }
    return widgets;
  }
}
Questão:
Como atualizar dinamicamente um ListView ?Responda:
Atualize a lista de dados e ligue setState().Diferenças:
Xamarin.Forms usa um ItemsSource para isso . No Flutter, após o setState()widget ser redesenhado novamente.Exemplo:
import 'package:flutter/material.dart';
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();
    for (int i = 0; i < 100; i++) {
      widgets.add(getRow(i));
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: ListView(children: widgets),
    );
  }
  Widget getRow(int i) {
    return GestureDetector(
      child: Padding(
        padding: EdgeInsets.all(10.0),
        child: Text("Row $i"),
      ),
      onTap: () {
        setState(() {
          widgets = List.from(widgets);
          widgets.add(getRow(widgets.length + 1));
          print('row $i');
        });
      },
    );
  }
}
Informação adicional:
Para criar uma lista, é recomendável usar o ListView.Builder .Exemplo:
import 'package:flutter/material.dart';
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();
    for (int i = 0; i < 100; i++) {
      widgets.add(getRow(i));
    }
  }
  @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 GestureDetector(
      child: Padding(
        padding: EdgeInsets.all(10.0),
        child: Text("Row $i"),
      ),
      onTap: () {
        setState(() {
          widgets.add(getRow(widgets.length + 1));
          print('row $i');
        });
      },
    );
  }
}
Texto
Questão:
Como usar fontes personalizadas?Responda:
O arquivo de fonte que você só precisa colocar em uma pasta (pense em um nome para si mesmo) e indique o caminho para ele pubspec.yaml.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'),
      ),
    ),
  );
}
Questão:
Como estilizar widgets de texto?Responda:
Usando parâmetros:- cor;
- decoração;
- decorationColor;
- decorationStyle;
- família de fontes;
- tamanho da fonte;
- estilo de fonte;
- espessura da fonte;
- hashCode;
- altura;
- herdar;
- letterSpacing;
- textBaseline;
- wordSpacing.
Questão:
Qual é o equivalente a Placeholder ?Responda:
O hintText propriedade de InputDecoration .Exemplo:
body: new Center(
  child: new TextField(
    decoration: new InputDecoration(hintText: "This is a hint"),
  )
)
Questão:
Como mostrar erros de validação?Responda:
Tudo o mesmo com InputDecoration e seu estado.Exemplo:
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> {
  String _errorText;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: Center(
        child: TextField(
          onSubmitted: (String text) {
            setState(() {
              if (!isEmail(text)) {
                _errorText = 'Error: This is not an email';
              } else {
                _errorText = null;
              }
            });
          },
          decoration: InputDecoration(hintText: "This is a hint", errorText: _getErrorText()),
        ),
      ),
    );
  }
  _getErrorText() {
    return _errorText;
  }
  bool isEmail(String emailString) {
    String emailRegexp =
        r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
    RegExp regExp = RegExp(emailRegexp);
    return regExp.hasMatch(emailString);
  }
}
Flutter Plugins
Questão:
Como acessar o GPS?Responda:
Usando o GeoLocator plug-in .Questão:
Como acessar a câmera?Responda:
Usando o plugin image_picker .Questão:
Como fazer login via Facebook?Responda:
Usando o plugin flutter_facebook_login .Questão:
Como usar o firebase?Responda:
O Firebase suporta plugins Flutter :Código específico da plataforma
Questão:
Como determinar em qual plataforma o código está sendo executado?Responda:
Usando a classe de campo platformem Theme ou a classe Platform .Exemplo:
Campo platform:if (Theme.of(context).platform == TargetPlatform.iOS) {
  return 'iOS';
} else if (Theme.of(context).platform == TargetPlatform.android) {
  return 'android';
} else if (Theme.of(context).platform == TargetPlatform.fuchsia) {
  return 'fuchsia';
} else {
  return 'not recognised ';
}
Classe da plataforma:if (Platform.isIOS) {
  return 'iOS';
} else if (Platform.isAndroid) {
  return 'android';
} else if (Platform.isFuchsia) {
  return 'fuchsia';
} else {
  return 'not recognised ';
}
Questão:
Como chamar código de plataforma nativa?Responda:
Via MethodChannel .Informação adicional:
Mais detalhes aqui .Depuração
Questão:
Quais são as ferramentas para depurar o aplicativo?Responda:
DevTools .Questão:
Como fazer hot reload?Responda:
Se o aplicativo foi iniciado a partir do IntelliJ IDE, Android Studio ou VSCode, combine ⌘s/ctrl-sou clique no ícone hot reload. Se iniciado a partir do terminal, digite uma letra r.Questão:
Como acessar o menu do desenvolvedor no aplicativo?Responda:
Se o lançamento foi do IDE, use as ferramentas do IDE. Se no console, use h.Informação adicional:
Lista completa de comandos:Armazenamento local
Questão:
Como armazenar key-valuedados no aplicativo?Responda:
Usando o plug-in shared_preferences .Diferenças:
No Xamarin.Forms é usado Xam.Plugins.Settings.Exemplo:
Dependência de conexão:dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^0.4.3
Usando:SharedPreferences prefs = await SharedPreferences.getInstance();
_counter = prefs.getInt('counter');
prefs.setInt('counter', ++_counter);
setState(() {
  _counter = _counter;
});
Questão:
Como armazenar dados complexos?Responda:
Usando plugins de banco de dados como sqflite ou hive .Aqui estão, talvez, as respostas para as perguntas básicas. Isso conclui a série de interpretações. Espero que tenham sido úteis para todos os desenvolvedores interessados neste framework. Talvez você tenha começado a escrever sobre o Flutter e o recrutado para uma comunidade amigável de desenvolvedores do Flutter. E irei pensar em novos artigos para desenvolver a comunidade e tornar o mundo dos aplicativos um lugar melhor. Que seus formulários não quebrem o Xamarin!