Flutter ya ha escrito muchos artículos. Cada mes se está volviendo más popular. Así que decidí interpretar la documentación oficial de Flutter en un formato conciso de preguntas y respuestas. Creo que muchos, como yo, no tienen suficiente tiempo libre para estudiar en detalle la documentación del marco con el que aún no funcionan.
Si desea comprender para qué sirve este marco y evaluar cuánto esfuerzo tendrá que hacer para usarlo, bienvenido a cat.

Contenido:
- Vistas
- Intenciones
- IU asíncrona
- Estructura del proyecto y recursos
- Actividades y fragmentos
- Diseños
- Gestos y manejo de eventos táctiles.
- Vistas de lista y adaptadores
- Trabajar con texto
- Formulario de entrada
- Flutter Plugins
- Temas
- Bases de datos y almacenamiento local.
- Notificaciones
Vistas
Pregunta:
¿Cuál es el equivalente de
Ver en Flutter?
La respuesta es:
WidgetDiferencias:
Ver: de hecho, lo que estará en la pantalla. Invalidate () se llama para mostrar los cambios.
Widget: una descripción de lo que aparecerá en la pantalla. Para el cambio se crea de nuevo.
Informacion adicional:
Cuando se inicia en Android, View está bajo el capó de Widget. Flutter incluye la biblioteca de
componentes de material . Contiene widgets que implementan
pautas de diseño de materiales .
Pregunta:
¿Cómo actualizar la visualización de widgets?
La respuesta es:
Usando
StatefulWidget y su
estado . Flutter tiene 2 tipos de widgets:
StatelessWidget y
StatefulWidget . Funcionan de la misma manera, la única diferencia está en el estado de representación.
Diferencias:
StatelessWidget tiene un estado inmutable. Adecuado para mostrar texto, logotipo, etc. Es decir Si el elemento en la pantalla no debe cambiar durante todo el tiempo de visualización, entonces le conviene. También se puede usar como contenedor para widgets con estado.
StatefulWidget tiene el estado State, que almacena información sobre el estado actual. Si desea cambiar un elemento en la pantalla al realizar alguna acción (una respuesta vino del servidor, el usuario hizo clic en un botón, etc.), esta es su opción.
Un ejemplo:
1) StatelessWidget - Texto
Text( 'I like Flutter!', style: TextStyle(fontWeight: FontWeight.bold), );
2) StatefulWidget: cuando hace clic en el botón (FloatingActionButton), el texto en el widget de texto cambia de "Me gusta Flutter" a "Flutter is Awesome!".
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Pregunta:
¿Cómo diseñar una pantalla con widgets? ¿Dónde está el archivo de diseño XML?
La respuesta es:
Flutter no tiene diseño XML para pantallas. Todo está compuesto en el árbol de widgets directamente en el código.
Un ejemplo:
@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 los widgets predeterminados en Flutter se pueden ver en el
catálogo de widgets .
Pregunta:
¿Cómo agregar o eliminar un componente en el diseño mientras se ejecuta la aplicación?
La respuesta es:
A través de una función que devolverá el widget deseado según el estado.
Diferencias:
En Android, puede hacer addView () o removeView () en un ViewGroup. En Flutter no es posible, porque los widgets no cambian. Solo su condición puede cambiar.
Un ejemplo:
Cómo cambiar Texto a Botón haciendo clic en FloatingActionButton.
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Pregunta:
¿Cómo animar widgets?
La respuesta es:
Usando la clase
AnimationController , que es el descendiente de la clase abstracta
Animation <T> . Además de comenzar la animación, puede pausarla, rebobinarla, detenerla y reproducirla en la dirección opuesta. Funciona con
Ticker , que informa sobre un nuevo dibujo de la pantalla.
Diferencias:
En Android, puede crear animaciones en XML o animar la vista usando animate (). En Flutter, la animación debe escribirse en código usando AnimationController.
Informacion adicional:
Puede obtener más información en los
widgets de animación y movimiento ,
tutorial de animaciones y
descripción general de animaciones .
Un ejemplo:
Animación desvanecida del logotipo de Flutter.
import 'package:flutter/material.dart'; void main() { runApp(FadeAppTest()); } class FadeAppTest extends StatelessWidget {
Pregunta:
¿Cómo usar
Canvas ?
La respuesta es:
Android y Flutter tienen la misma API para Canvas, ya que usan el mismo motor
Skia de bajo nivel.
Diferencias:
No
Informacion adicional:
Flutter tiene dos clases para dibujar en Canvas:
CustomPaint y
CustomPainter . El segundo implementa su algoritmo de renderizado.
Lea más aquí:
StackOverflowUn ejemplo:
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; }
Pregunta:
¿Cómo crear widgets personalizados?
La respuesta es:
Componga widgets dentro de uno (en lugar de herencia).
Diferencias:
En Android, podemos heredar de la Vista que nos interesa y agregar nuestra propia lógica. En Flutter, esto es similar a un ViewGroup, solo el widget siempre se hereda de StatelessWidget o StatefulWidget. Es decir debe crear un nuevo widget y usarlo como el conjunto de widgets que necesita como parámetros o campos.
Un ejemplo:
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"), ); }
Intenciones
Pregunta:
¿Cuál es el análogo de
Intención en Flutter?
La respuesta es:
El no esta ahi. Para navegar entre pantallas, se utilizan las clases
Navegador y
Ruta .
Para interactuar con componentes externos (por ejemplo, una cámara o un selector de archivos), puede usar
complementos o integración nativa en cada plataforma. Obtenga más información sobre la integración nativa:
desarrollo de paquetes y complementos .
Diferencias:
Flutter no tiene tal cosa como actividad y fragmento. Hay Navigator (Navigator) y Rutas (rutas). La aplicación Flutter se asemeja a una aplicación de una sola actividad, donde diferentes pantallas representan diferentes fragmentos, y el FragmentManager los controla. Navigator es similar al FragmentManager en principio. Puede hacer
push () o
pop () a la ruta que especifique. La ruta es un tipo de fragmento, pero en Flutter es habitual compararlo con una pantalla o página.
En Android, describimos todas las actividades entre las que podemos navegar en AndroidManifest.xml.
Flutter tiene dos formas:
- Describa un mapa llamado Ruta (MaterialApp)
- Navega directamente a Ruta (WidgetApp).
Un ejemplo:
void main() { runApp(MaterialApp( home: MyAppHome(),
Pregunta:
¿Cómo procesar intentos provenientes de otras aplicaciones?
La respuesta es:
Interactuando con la capa de Android de la aplicación a través de
MethodChannel .
Un ejemplo:
Escribimos intent-filter en 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>
Procesamos la intención en MainActivity y llamamos al código desde Flutter a través de 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 datos cuando el widget comienza a dibujarse:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Pregunta:
¿Cuál es el análogo de
startActivityForResult () ?
La respuesta es:
La palabra clave aguarda y el resultado de una
clase Futuro .
Diferencias:
Después de llamar a startActivityForResult () en Android, necesitamos implementar el procesamiento en onActivityResult (). Flutter no necesita implementar nada, porque El método de navegador push () devuelve un objeto Future.
Un ejemplo:
Map coordinates = await Navigator.of(context).pushNamed('/location');
Y cuando tengamos las coordenadas en la pantalla '/ ubicación', haga pop ():
Navigator.of(context).pop({"lat":43.821757,"long":-79.226392});
IU asíncrona
Pregunta:
¿Cuál es el análogo de
runOnUiThread () en Flutter?
La respuesta es:
Dart implementa un modelo de ejecución de subproceso único que se ejecuta en
aislamientos . La ejecución asincrónica usa async / await, con la que puede estar familiarizado desde C #, JavaScript o las rutinas de Kotlin.
Un ejemplo:
Cumplir la solicitud y devolver el resultado para actualizar la interfaz de usuario:
loadData() async { String dataURL = "https://jsonplaceholder.typicode.com/posts"; http.Response response = await http.get(dataURL); setState(() { widgets = json.decode(response.body); }); }
Cuando se recibe la respuesta a la solicitud, debe llamar al método
setState () para volver a dibujar el árbol de widgets con los nuevos datos.
Un ejemplo:
Cargando y actualizando datos en un
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); }); } }
Pregunta:
¿Cómo ejecutar código en un hilo de fondo?
La respuesta es:
Como se mencionó anteriormente, utilizando async / await y aislamiento (Isolate).
Diferencias:
Fuera de la caja en Android, puede usar AsyncTask.
Debe implementar
onPreExecute () ,
doInBackground () ,
onPostExecute () en él . En Flutter "fuera de la caja" solo necesita usar async / wait, Dart se encargará del resto.
Un ejemplo:
Aquí el método dataLoader () está aislado. De forma aislada, puede ejecutar operaciones pesadas como analizar JSON grandes, cifrado, procesamiento de imágenes, etc.
loadData() async { ReceivePort receivePort = ReceivePort(); await Isolate.spawn(dataLoader, receivePort.sendPort);
Pregunta:
¿Cuál es el equivalente de Flutter de
OkHttp ?
La respuesta es:
Flutter tiene su propio
paquete HTTP .
Informacion adicional:
Hasta ahora, no todas las características OkHttp se han implementado en el paquete HTTP, por lo que muchas de las características que faltan se abstraen y puede implementarlas usted mismo según sea necesario.
Un ejemplo:
Para usar el paquete HTTP, agréguelo como una dependencia en pubspec.yaml:
dependencies: ... http: ^0.11.3+16
Para ejecutar la solicitud, llame en espera en la función asincrónica 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); }); } }
Pregunta:
¿Cómo mostrar el progreso?
La respuesta es:
Usando el widget
ProgressIndicator .
Un ejemplo:
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); }); } }
Estructura del proyecto y recursos
Pregunta:
¿Dónde almacenar recursos de diferentes resoluciones?
La respuesta es:
En activos.
Diferencias:
En Android, los recursos tienen una carpeta res y tienen activos. Flutter solo tiene activos. La carpeta de activos se puede ubicar en cualquier parte del proyecto, lo más importante es escribir la ruta en el archivo pubspec.yaml.
Informacion adicional:
Comparación de los tamaños de los recursos gráficos en Android y Flutter.
Flutter usa AssetManager o clases especializadas que comienzan con Asset para usar recursos en el código.
Un ejemplo:
AssetManager:
val flutterAssetStream = assetManager.open("flutter_assets/assets/my_flutter_asset.png")
Ubicación del 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
Ruta en el archivo pubspec.yaml:
assets: - images/my_icon.jpeg
Usando
AssetImage :
return AssetImage("images/a_dot_burr.jpeg");
Usando el activo directamente:
@override Widget build(BuildContext context) { return Image.asset("images/my_image.png"); }
Pregunta:
¿Dónde almacenar cadenas? ¿Cómo localizarlos?
La respuesta es:
Almacenar en campos estáticos. Localizar usando el
paquete intl .
Un ejemplo:
class Strings { static String welcomeMessage = "Welcome To Flutter"; } Text(Strings.welcomeMessage)
Pregunta:
¿Cuál es el análogo del archivo gradle? ¿Cómo agregar dependencias?
La respuesta es:
pubspec.yaml.
Informacion adicional:
Flutter delega el ensamblaje a los creadores nativos de Android e iOS. Vea una lista de todas las bibliotecas populares para Flutter en
Pub .
Actividades y fragmentos
Pregunta:
¿Cuál es el equivalente de
Actividad y
Fragmento en Flutter?
La respuesta es:
Todo en Flutter son widgets. Los widgets juegan el papel de la actividad y los fragmentos para trabajar con la interfaz de usuario. Y el papel de la navegación, como se menciona en el párrafo sobre navegación, es Navegador y Ruta.
Informacion adicional:
Flutter para desarrolladores de Android: cómo diseñar una IU de actividad en Flutter .
Pregunta:
¿Cómo manejar los eventos del ciclo de vida?
La respuesta es:
Usando el
método WidgetsBinding y
didChangeAppLifecycleState () .
Informacion adicional:
Flutter usa FlutterActivity en código nativo, y el motor Flutter hace que los cambios de estado de procesamiento sean lo más discretos posible. Pero si aún necesita hacer algún trabajo dependiendo del estado, el ciclo de vida es ligeramente diferente:
- inactivo: este método es solo en iOS, en Android no hay análogo;
- en pausa: similar a onPause () en Android;
- resumido: similar a onPostResume () en Android;
- suspensión: similar a onStop en Android, en iOS no hay análogo.
Esto se describe con más detalle en la
documentación de AppLifecycleStatus .
Un ejemplo:
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())); }
Diseños
Pregunta:
¿Cuál es el análogo de
LinearLayout ?
La respuesta es:
Fila para horizontal,
columna para vertical.
Informacion adicional:
Flutter para desarrolladores de Android: ¿Cómo diseñar LinearLayout en Flutter?Un ejemplo:
@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'), ], ); }
Pregunta:
¿Cuál es el equivalente de
RelativeLayout ?
La respuesta es:
Pila de widgets.
Más detalles:
StackoverflowPregunta:
¿Cuál es el análogo de
ScrollView ?
La respuesta es:
ListView con widgets.
Un ejemplo:
@override Widget build(BuildContext context) { return ListView( children: <Widget>[ Text('Row One'), Text('Row Two'), Text('Row Three'), Text('Row Four'), ], ); }
Pregunta:
¿Cómo manejar las transiciones entre retrato y paisaje?
La respuesta es:
FlutterView maneja los flips si AndroidManifest.xml contiene
android: configChanges = "orientación | tamaño de pantalla"
Gestos y manejo de eventos táctiles
Pregunta:
¿Cómo agregar onClick listener para widget en Flutter?
La respuesta es:
Si el widget admite clics, entonces en onPressed (). Si no, entonces en onTap ().
Un ejemplo:
En onPressed ():
@override Widget build(BuildContext context) { return RaisedButton( onPressed: () { print("click"); }, child: Text("Button")); }
En onTap ():
class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: GestureDetector( child: FlutterLogo( size: 200.0, ), onTap: () { print("tap"); }, ), )); } }
Pregunta:
¿Cómo manejar otros gestos en widgets?
La respuesta es:
Usando el
GestureDetector . Pueden manejar las siguientes acciones:
Toque
Doble toque
Pulsación larga
Arrastre vertical
Arrastre horizontal
Un ejemplo:
Procesamiento en DoubleTap:
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(); } }, ), )); } }
Vistas de lista y adaptadores
Pregunta:
¿Cuál es el análogo de
ListView en Flutter?
La respuesta es:
ListViewDiferencias:
Flutter no tiene que pensar en limpiar y reutilizar elementos (que es lo que hace ListView / RecyclerView en Android, usando el patrón ViewHolder).
Un ejemplo:
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Pregunta:
¿Cómo averiguar en qué elemento se hizo clic?La respuesta es:
Envolver un elemento en un GestureDetector .Un ejemplo:
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Pregunta:
¿Cómo actualizar dinámicamente un ListView ?La respuesta es:
Si tiene un pequeño conjunto de datos, esto se puede hacer a través de setState () . Si el conjunto de datos es grande, entonces a través de ListView.Builder , que es un análogo de RecyclerView .Un ejemplo:
Usando setState () : import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Usando ListView.Builder : import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Trabajar con texto
Pregunta:
¿Cómo usar fuentes personalizadas?La respuesta es:
Solo necesita poner el archivo de fuente en la carpeta (piense en el nombre usted mismo) e indique la ruta en pubspec.yaml.Un ejemplo:
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'), ), ), ); }
Pregunta:
¿Cómo diseñar widgets de texto?La respuesta es:
Usando parámetros:- color
- decoracion
- decorationColor;
- decorationStyle;
- fontFamily;
- fontSize;
- fontStyle;
- fontWeight;
- hashCode;
- height;
- inherit;
- letterSpacing;
- textBaseline;
- wordSpacing.
:
Retrieve the value of a text field .
:
hint
TextInput ?
La respuesta es:
InputDecoration , .
Un ejemplo:
body: Center( child: TextField( decoration: InputDecoration(hintText: "This is a hint"), ) )
:
?
La respuesta es:
—
InputDecoration .
Un ejemplo:
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Flutter
:
GPS?
La respuesta es:
geolocator .
:
?
La respuesta es:
image_picker .
:
Facebook?
La respuesta es:
flutter_facebook_login .
:
Firebase?
La respuesta es:
Firebase
Flutter first party plugins .
:
() ?
La respuesta es:
Flutter EventBus . :
developing packages and plugins .
:
NDK?
La respuesta es:
NDK- Flutter. Flutter .
Themes
:
(Theme) ?
La respuesta es:
MaterialApp WidgetApp .
Un ejemplo:
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?
La respuesta es:
Shared_Preferences plugin ( NSUserDefaults iOS ).
Un ejemplo:
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?
La respuesta es:
SQFlite .
Notificaciones
:
push-?
La respuesta es:
Firebase_Messaging .
Conclusión
. , , . « » . «-» . , ? 2016 Kotlin, - 2017. , , . , .
2016 Flutter Dart. , 2018 . . ! , , , . ( Google Fuchsia , , , Flutter ). — ! , — . Eso es todo para mí. Google Play!