Continuamos a interpretação lacônica da
documentação oficial do Flutter em um formato de perguntas e respostas. Esta é a terceira parte e será mais útil para reagir aos desenvolvedores nativos. Nesta interpretação, você pode encontrar respostas para perguntas freqüentes e determinar por si mesmo quanto esforço você precisa fazer para mudar de uma estrutura de plataforma cruzada para outra.

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 nativosFlutter. Parte 4. Para Desenvolvedores da Web
Flutter. Parte 5. Para desenvolvedores do Xamarin.Forms
Conteúdo:
- Um pouco sobre Dart
- O básico
- Estrutura e Recursos do Projeto
- Visualizações
- Layouts
- Estilização
- Gestão estatal
- Armazenamento local
- Navegação
- Gestos e manipulação de eventos por toque
- Solicitações HTTP
- Formulário de entrada
- Código específico da plataforma
- Depuração
- Animação
- Equivalentes de componentes
- Flutter Plugins
Um pouco sobre Dart
Pergunta:
Onde fica o ponto de entrada?
A resposta é:
Função
main()
.
Diferenças:
O JavaScript não tem um ponto de entrada predefinido; pode ser qualquer função definida pelo desenvolvedor. No Dart, isso é apenas
main()
.
Pergunta:
Como enviar para o console?
A resposta é:
Usando a função
print()
.
Diferenças:
Em JavaScript, a saída do console é feita usando
console.log()
.
Um exemplo:
print('Hello world!');
Pergunta:
Como criar e atribuir variáveis / campos?
A resposta é:
O Dart suporta digitação dinâmica e forte. Portanto, variáveis / campos podem ser criados em qualquer tipo de digitação que seja conveniente para você. A atribuição ocorre através de um único.
Diferenças:
A digitação forte não é suportada em JavaScript.
Informações adicionais:
Mais detalhes aqui.Um exemplo:
String name = 'dart';
Pergunta:
Qual é o valor padrão de uma variável / campo?
A resposta é:
null
Diferenças:
JavaScript está
undefined
por padrão.
Informações adicionais:
Mais detalhes aqui.Pergunta:
Como verificar um valor para
null
ou para 0?
A resposta é:
Usando verificação explícita
==
.
Diferenças:
Em JavaScript, como parte da verificação
if
número é 1 ou qualquer objeto
non-null
será equivalente a
true
. No Dart, apenas um valor booleano de
true
equivalente a
true
.
Um exemplo:
var myNull = null; if (myNull == null) { print('use "== null" to check null'); } var zero = 0; if (zero == 0) { print('use "== 0" to check zero'); }
Pergunta:
Como declarar funções?
A resposta é:
No Dart, funções, como campos, podem ser com digitação dinâmica ou forte do valor de retorno. Os tipos dinamicamente digitados são declarados simplesmente pelo nome da função e, opcionalmente, pelos parâmetros, enquanto os tipos fortemente digitados no início ainda têm um tipo de retorno.
Diferenças:
Em JavaScript, uma função é declarada com a
function
palavra-chave, seguida por um nome e, opcionalmente, por parâmetros.
Informações adicionais:
Mais detalhes aqui.Um exemplo:
fn() { return true; }
Pergunta:
Qual é o equivalente a
Promessa ?
A resposta é:
FuturoInformações adicionais:
O dardo, como o JavaScript, suporta a execução de thread único.
Futuro em Dart tem o mesmo significado que
Promise in React Native.
Mais detalhes aqui. .
Um exemplo:
import 'dart:convert'; import 'package:http/http.dart' as http; class Example { Future<String> _getIPAddress() { final url = 'https://httpbin.org/ip'; return http.get(url).then((response) { String ip = jsonDecode(response.body)['origin']; return ip; }); } } main() { final example = new Example(); example ._getIPAddress() .then((ip) => print(ip)) .catchError((error) => print(error)); }
Pergunta:
Qual é o análogo de
async
e
await
?
A resposta é:
async
e
await
Diferenças:
No JavaScript, as funções assíncronas retornam
Promise , no Dart, elas retornam
Future . aguardar espera de forma síncrona o resultado da chamada de uma função assíncrona.
Informações adicionais:
Mais detalhes aqui.Um exemplo:
import 'dart:convert'; import 'package:http/http.dart' as http; class Example { Future<String> _getIPAddress() async { final url = 'https://httpbin.org/ip'; final response = await http.get(url); String ip = jsonDecode(response.body)['origin']; return ip; } } main() async { final example = new Example(); try { final ip = await example._getIPAddress(); print(ip); } catch (error) { print(error); } }
O básico
Pergunta:
Como criar um projeto de aplicativo no Flutter?
A resposta é:
- Usando o IDE com os plug-ins Flutter e Dart instalados.
- Usando o
flutter create {projectname}
.
Diferenças:
Para criar um projeto no React Native, use o
create-react-native-app {projectname}
.
Informações adicionais:
Mais detalhes aqui.Pergunta:
Como iniciar o aplicativo?
A resposta é:
- Usando a função de execução no IDE com os plug-ins Flutter e Dart instalados.
- Usando o comando
flutter run
.
Diferenças:
O React Native usa os
npm run
ou
yarn run
para iniciar o aplicativo.
Pergunta:
Como importar widgets?
A resposta é:
No Flutter, todos os widgets são divididos em pacotes, portanto, importar um pacote é suficiente para usar seus widgets.
Diferenças:
No React Native, você precisa importar cada widget.
Um exemplo:
import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter/my_widgets.dart';
Pergunta:
Como usar widgets e aninhamento para construir uma árvore de widgets?
A resposta é:
No Flutter, quase tudo são widgets. Até o objeto do aplicativo é um widget. Cada widget pode ser aninhado no pai. Ao combinar widgets, você constrói uma hierarquia chamada árvore de widgets. É ela quem mais tarde se transforma em uma exibição na tela.
Um exemplo:
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: Scaffold( appBar: AppBar( title: Text('Welcome to Flutter'), ), body: Center( child: Text('Hello world'), ), ), ); } }
Pergunta:
Como criar componentes reutilizáveis?
A resposta é:
No Flutter, você pode criar uma classe de widget e reutilizá-la. Os parâmetros usados são campos de classe.
Diferenças:
No React Native, para alterar os parâmetros de um elemento reutilizado, é necessário marcá-los como acessórios.
Informações adicionais:
Os parâmetros no construtor podem ser declarados de duas maneiras: por enumeração regular e opcional, usando chaves
{}
. As diferenças ocorrem ao usar parâmetros para chamar o construtor.
Na enumeração usual, todos os parâmetros são necessários e, ao chamar o construtor, você não pode especificar qual parâmetro específico é passado, porque eles são devidos ao pedido.
Com o opcional, é possível usar qualquer ordem na qual os parâmetros são transmitidos, mas você deve especificar qual parâmetro específico é transmitido ou não transmiti-los. Para marcar um parâmetro opcional conforme necessário, use a anotação
@required
.
Um exemplo:
class CustomCard extends StatelessWidget { CustomCard({@required this.index, @required this.onPress}); final index; final Function onPress; @override Widget build(BuildContext context) { return Card( child: Column( children: <Widget>[ Text('Card $index'), FlatButton( child: const Text('Press'), onPressed: this.onPress, ), ], ) ); } } ...
Estrutura e Recursos do Projeto
Pergunta:
Por onde começar a escrever código?
A resposta é:
Em
{projectname}/lib/main.dart
.
Pergunta:
Qual é a estrutura do arquivo em um projeto Flutter?
A resposta é:
┬ └ projectname ┬ ├ android - Android . ├ build - iOS Android . ├ ios - iOS . ├ lib - Dart . ┬ └ src - Contains additional source files. └ main.dart - . ├ test - . └ pubspec.yaml - . package.json React Native.
Pergunta:
Onde armazenar recursos e ativos e como usá-los?
A resposta é:
Links para recursos e dependências do projeto são armazenados no arquivo
pubspec.yaml
. De fato, você pode colocá-los em qualquer pasta dentro da
lib
, o mais importante, especificar o caminho para eles em
pubspec.yaml
. Você pode usá-los em um projeto usando widgets especializados, por exemplo,
AssetImage ou diretamente usando
AssetBundle .
Informações adicionais:
Mais detalhes aqui.Um exemplo:
Declarando ativos em
pubspec.yaml
flutter: assets: - assets/my_icon.png - assets/background.png
Use no código
image: AssetImage('assets/background.png'),
Pergunta:
Como baixar imagens da rede?
A resposta é:
Usando
Image.network .
Um exemplo:
body: Image.network( 'https://flutter.io/images/owl.jpg',
Pergunta:
Como conectar pacotes e plugins de terceiros?
A resposta é:
Usando
dependencies
no
pubspec.yaml
.
Diferenças:
O React Native usa os comandos
yarn add {package-name}
ou
npm install --save {package-name}
para adicionar dependências.
Informações adicionais:
Usando PacotesDesenvolvimento de pacotes e pluginsPlugins populares para FlutterUm exemplo:
dependencies: flutter: sdk: flutter google_sign_in: ^3.0.3
Visualizações
Pergunta:
Qual é o equivalente a um contêiner
View ?
A resposta é:
Todos os widgets básicos para o layout, por exemplo
Contêiner ,
Coluna ,
Linha e
Centro .
Informações adicionais:
Mais detalhes aqui.Pergunta:
Qual é o análogo do
FlatList ou
SelectionList ?
A resposta é:
ListviewUm exemplo:
var data = [ ... ]; ListView.builder( itemCount: data.length, itemBuilder: (context, int index) { return Text( data[index], ); }, )
Pergunta:
Como usar o Canvas?
A resposta é:
Usando as
classes CustomPaint e
CustomPainter .
Diferenças:
No React Native, não há como desenhar usando o Canvas imediatamente. Existem plugins de terceiros, por exemplo,
react-native-canvas
.
Um exemplo:
class MyCanvasPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { Paint paint = Paint(); paint.color = Colors.amber; canvas.drawCircle(Offset(100.0, 200.0), 40.0, paint); Paint paintRect = Paint(); paintRect.color = Colors.lightBlue; Rect rect = Rect.fromPoints(Offset(150.0, 300.0), Offset(300.0, 400.0)); canvas.drawRect(rect, paintRect); } bool shouldRepaint(MyCanvasPainter oldDelegate) => false; bool shouldRebuildSemantics(MyCanvasPainter oldDelegate) => false; } class _MyCanvasState extends State<MyCanvas> { @override Widget build(BuildContext context) { return Scaffold( body: CustomPaint( painter: MyCanvasPainter(), ), ); } }
Layouts
Pergunta:
Como usar widgets para descrever propriedades de layout?
A resposta é:
O Flutter usa widgets especializados para propriedades de layout, por exemplo:
Coluna ,
Linha ,
Preenchimento ,
Alinhar ,
Pilha .
Diferenças:
No React Native, na maioria das vezes as propriedades do layout podem ser definidas usando
props
.
Informações adicionais:
Lista completa de widgetsPergunta:
Como posicionar widgets no layout?
A resposta é:
Para posicionamento absoluto, use o widget
Pilha . Para o parente - vários widgets e suas combinações, que podem ser encontrados
aqui .
Um exemplo:
Stack( alignment: const Alignment(0.6, 0.6), children: <Widget>[ CircleAvatar( backgroundImage: NetworkImage( 'https://avatars3.githubusercontent.com/u/14101776?v=4'), ), Container( decoration: BoxDecoration( color: Colors.black45, ), child: Text('Flutter'), ), ], )
Estilização
Pergunta:
Como modelar componentes?
A resposta é:
Na maioria das vezes, os widgets têm uma propriedade de
style
.
Diferenças:
O React Native usa
stylesheets.create
para estilizar.
Um exemplo:
var textStyle = TextStyle(fontSize: 32.0, color: Colors.cyan, fontWeight: FontWeight.w600); ... Center( child: Column( children: <Widget>[ Text( 'Sample text', style: textStyle, ), Padding( padding: EdgeInsets.all(20.0), child: Icon(Icons.lightbulb_outline, size: 48.0, color: Colors.redAccent) ), ], ), )
Pergunta:
Como usar ícones e cores?
A resposta é:
Usando as classes
Ícones e
Cores .
Diferenças:
O React Native não possui suporte de ícone pronto para uso.
Um exemplo:
Ícones
Icon(Icons.lightbulb_outline, color: Colors.redAccent)
Cores
class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Sample App', theme: ThemeData( primarySwatch: Colors.blue, textSelectionColor: Colors.red ), home: SampleAppPage(), ); } }
Pergunta:
Como personalizar o tema estilístico do aplicativo?
A resposta é:
Usando a classe
ThemeData .
Diferenças:
No React Native, um tema comum é configurado através de
stylesheets
.
Um exemplo:
@override Widget build(BuildContext context) { return Theme( data: ThemeData( primaryColor: Colors.cyan, brightness: brightness, ), child: Scaffold( backgroundColor: Theme.of(context).primaryColor, ... ... ), ); }
Gestão estatal
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 flutter para
Flutter é impressionante! import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Armazenamento local
Pergunta:
Como armazenar dados de
key-value
em um aplicativo?
A resposta é:
Usando o plug-in
shared_preferences .
Diferenças:
O React Native usa
AsyncStorage .
Um exemplo:
Dependência
dependencies: flutter: sdk: flutter shared_preferences: ^0.4.3
Use
SharedPreferences prefs = await SharedPreferences.getInstance(); _counter = prefs.getInt('counter'); prefs.setInt('counter', ++_counter); setState(() { _counter = _counter; });
Pergunta:
Como armazenar dados complexos?
A resposta é:
Usando plugins de banco de dados, por exemplo,
sqflite ou
hive .
Navegação
Pergunta:
Como navegar entre telas?
A resposta é:
Para navegar entre as telas, as classes
Navegador e
Rota são usadas.
Diferenças:
O React Native usa
StackNavigator ,
TabNavigator e
DrawerNavigator .
O Flutter possui dois métodos de navegação:
- Descrever um mapa com nomes de rotas
- Navegue diretamente para a rota .
O Navegador pode
pressionar () ou
pop () para a rota especificada.
Um exemplo:
void main() { runApp(CupertinoApp( home: MyAppHome(),
Pergunta:
Como usar a navegação por guias?
A resposta é:
Usando classes:
TabController ,
TabBar ,
Tab e
TabBarView .
Diferenças:
O React Native usa
createBottomTabNavigator e TabNavigation .
Informações adicionais:
Mais detalhes aqui. .
Um exemplo:
class _NavigationHomePageState extends State<NavigationHomePage> with SingleTickerProviderStateMixin { TabController controller=TabController(length: 2, vsync: this); @override Widget build(BuildContext context) { return Scaffold( bottomNavigationBar: Material ( child: TabBar( tabs: <Tab> [ Tab(icon: Icon(Icons.person),) Tab(icon: Icon(Icons.email),), ], controller: controller, ), color: Colors.blue, ), body: TabBarView( children: <Widget> [ home.homeScreen(), tabScreen.tabScreen() ], controller: controller, ) ); } }
Pergunta:
Como usar a navegação na gaveta?
A resposta é:
Usando a classe
Drawer .
Diferenças:
O React Native usa
createDrawerNavigator e DrawerNavigation .
Um exemplo:
@override Widget build(BuildContext context) { return Scaffold( drawer: Drawer( child: ListTile( leading: Icon(Icons.change_history), title: Text('Screen2'), onTap: () { Navigator.of(context).pushNamed('/b'); }, ), elevation: 20.0, ), appBar: AppBar( title: Text('Home'), ), body: Container(), ); }
Gestos e manipulação de eventos por toque
Pergunta:
Como lidar com um clique?
A resposta é:
Se o widget suportar cliques, em
onPressed()
. Caso contrário, use o widget
GestureDetector .
Diferenças:
O React Native usa
PanResponder ou
Touchable para isso.
Um exemplo:
GestureDetector( child: Scaffold( appBar: AppBar( title: Text('Gestures'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('Tap, Long Press, Swipe Horizontally or Vertically '), ], ) ), ), onTap: () { print('Tapped'); }, onLongPress: () { print('Long Pressed'); }, onVerticalDragEnd: (DragEndDetails value) { print('Swiped Vertically'); }, onHorizontalDragEnd: (DragEndDetails value) { print('Swiped Horizontally'); }, );
Solicitações HTTP
Pergunta:
Como obter dados de solicitações de API?
A resposta é:
Usando um
plugin http .
Diferenças:
O React Native usa a
fetch API
.
Um exemplo:
Conexão de plug-in
dependencies: flutter: sdk: flutter http: <latest_version>
Recuperação de dados
final url = Uri.https('httpbin.org', 'ip'); final httpClient = HttpClient(); _getIPAddress() async { var request = await httpClient.getUrl(url); var response = await request.close(); var responseBody = await response.transform(utf8.decoder).join(); String ip = jsonDecode(responseBody)['origin']; setState(() { _ipAddress = ip; }); }
Formulário de entrada
Pergunta:
Quais widgets usar para entrada?
A resposta é:
TextField em conjunto com
TextEditingController ou
TextFormField .
Diferenças:
O React Native usa
TextInput .
O TextFormField difere do
TextField em sua validação e lógica internas para armazenar valores em campos.
Um exemplo:
Textfield
final TextEditingController _controller = TextEditingController(); ... TextField( controller: _controller, decoration: InputDecoration( hintText: 'Type something', labelText: 'Text Field ' ), ), RaisedButton( child: Text('Submit'), onPressed: () { showDialog( context: context, child: AlertDialog( title: Text('Alert'), content: Text('You typed ${_controller.text}'), ), ); }, ), )
TextFormField
final formKey = GlobalKey<FormState>(); ... Form( key:formKey, child: Column( children: <Widget>[ TextFormField( validator: (value) => !value.contains('@') ? 'Not a valid email.' : null, onSaved: (val) => _email = val, decoration: const InputDecoration( hintText: 'Enter your email', labelText: 'Email', ), ), RaisedButton( onPressed: _submit, child: Text('Login'), ), ], ), ) void _submit() { final form = formKey.currentState; if (form.validate()) { form.save(); showDialog( context: context, child: AlertDialog( title: Text('Alert'), content: Text('Email: $_email, password: $_password'), ) ); } }
Código específico da plataforma
Pergunta:
Como determinar em qual plataforma o código está sendo executado?
A resposta é:
Usando a classe de campo da
platform
em
Theme ou a classe
Platform .
Um exemplo:
Campo da plataforma
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 de plataforma
if (Platform.isIOS) { return 'iOS'; } else if (Platform.isAndroid) { return 'android'; } else if (Platform.isFuchsia) { return 'fuchsia'; } else { return 'not recognised '; }
Pergunta:
Como chamar código de plataforma nativa?
A resposta é:
Via
MethodChannel .
Informações adicionais:
Mais detalhes aqui. .
Depuração
Pergunta:
Quais são as ferramentas para depurar o aplicativo?
A resposta é:
DevToolsPergunta:
Como fazer
hot reload
?
A resposta é:
Se o aplicativo foi iniciado a partir do IntelliJ IDE ou Android Studio,
⌘s/ctrl-s
ou clique no ícone de
hot reload
a
hot reload
. Se iniciado a partir do terminal, digite a letra
r
.
Diferenças:
O React Native usa o
⌘R/Ctrl+R
para emuladores iOS, o
R
duplo para Android.
Pergunta:
Como acessar o menu do desenvolvedor no aplicativo?
A resposta é:
Se o lançamento foi do IDE, use as ferramentas do IDE. Se no console, use h.
Diferenças:
O React Native usa
⌘D/Ctrl+D
para emuladores iOS e
⌘M/Ctrl+M
para Android.
Informações adicionais:
Lista completa de equipes
Animação
Pergunta:
O que é usado para animação?
A resposta é:
Animação e
AnimationController .
Diferenças:
O React Native usa a
Animation API
.
Informações adicionais:
Mais detalhes aqui.Pergunta:
Como adicionar uma simples animação
fade-in
?
A resposta é:
Usando
FadeTransition .
Um exemplo:
import 'package:flutter/material.dart'; void main() { runApp(Center(child: LogoFade())); } class LogoFade extends StatefulWidget { _LogoFadeState createState() => _LogoFadeState(); } class _LogoFadeState extends State<LogoFade> with TickerProviderStateMixin { Animation animation; AnimationController controller; initState() { super.initState(); controller = AnimationController( duration: const Duration(milliseconds: 3000), vsync: this); final CurvedAnimation curve = CurvedAnimation(parent: controller, curve: Curves.easeIn); animation = Tween(begin: 0.0, end: 1.0).animate(curve); controller.forward(); } Widget build(BuildContext context) { return FadeTransition( opacity: animation, child: Container( height: 300.0, width: 300.0, child: FlutterLogo(), ), ); } dispose() { controller.dispose(); super.dispose(); } }
Pergunta:
Como adicionar animação deslizante para listar itens?
A resposta é:
Usando não
permitido .
Um exemplo:
child: Dismissible( key: key, onDismissed: (DismissDirection dir) { cards.removeLast(); }, child: Container( ... ), ),
Equivalentes de componentes
Pergunta:
Quais são os equivalentes do Flutter em comparação com o React Native?
A resposta é:
Flutter Plugins
Pergunta:
Como acessar o GPS?
A resposta é:
Usando o plugin geolocator.
Pergunta:
Como acessar a câmera?
A resposta é:
Usando o plugin
image_picker .
Pergunta:
Como fazer login via Facebook?
A resposta é:
Usando o plugin
flutter_facebook_login .
Pergunta:
Como usar o firebase?
A resposta é:
O Firebase suporta
plugins Flutter :
Aqui estão, talvez, as respostas para as perguntas básicas. Espero que minha interpretação tenha sido útil para você, e se você ainda não está escrevendo sobre Flutter, pense pelo menos. Isso significa que pode haver um acréscimo à prateleira Flutter dos desenvolvedores e, juntos, tornaremos o mundo um lugar melhor através do prisma de aplicativos convenientes e rápidos desenvolvidos! Sim Reagir não quebrará seu nativo!