Flutter a déjà écrit de nombreux articles. Chaque mois, il devient de plus en plus populaire. J'ai donc décidé d'interpréter la documentation officielle de Flutter dans un format Q & A concis. Je pense que beaucoup, comme moi, n'ont pas assez de temps libre pour étudier en détail la documentation du cadre avec lequel ils ne fonctionnent toujours pas.
Si vous voulez comprendre à quoi sert ce cadre et évaluer combien d'efforts vous devrez faire pour l'utiliser, bienvenue à cat.

Contenu:
- Vues
- Intentions
- Async ui
- Structure et ressources du projet
- Activités et fragments
- Disposition
- Gestes et gestion des événements tactiles.
- Vues de liste et adaptateurs
- Travailler avec du texte
- Formulaire de saisie
- Plugins Flutter
- Thèmes
- Bases de données et stockage local
- Notifications
Vues
Question:
Quel est l'équivalent de
View in Flutter?
La réponse est:
WidgetDifférences:
Voir - en fait, ce qui sera à l'écran. Invalidate () est appelé pour afficher les modifications.
Widget - une description de ce qui sera à l'écran. Car le changement est créé à nouveau.
Information complémentaire:
Lorsqu'il est lancé sur Android lui-même, View est sous le capot de Widget. Flutter comprend la bibliothèque de
composants de matériaux . Il contient des widgets qui mettent en œuvre
les directives de conception des matériaux .
Question:
Comment mettre à jour l'affichage des widgets?
La réponse est:
Utilisation de
StatefulWidget et de son
état . Flutter a 2 types de widgets:
StatelessWidget et
StatefulWidget . Ils fonctionnent de la même manière, la seule différence est dans l'état de rendu.
Différences:
StatelessWidget a un état immuable. Convient pour afficher du texte, un logo, etc. C'est-à-dire si l'élément à l'écran ne doit pas changer pendant toute la durée d'affichage, cela vous convient. Il peut également être utilisé comme conteneur pour les widgets avec état.
StatefulWidget a l'état State, qui stocke des informations sur l'état actuel. Si vous souhaitez modifier un élément à l'écran lors de l'exécution d'une action (une réponse est venue du serveur, l'utilisateur a cliqué sur un bouton, etc.) - c'est votre option.
Un exemple:
1) StatelessWidget - Texte
Text( 'I like Flutter!', style: TextStyle(fontWeight: FontWeight.bold), );
2) StatefulWidget - lorsque vous cliquez sur le bouton (FloatingActionButton), le texte du widget Texte passe de «J'aime Flutter» à «Flutter is Awesome!».
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Question:
Comment mettre en page un écran avec des widgets? Où est le fichier de disposition XML?
La réponse est:
Flutter n'a pas de disposition XML pour les écrans. Tout est composé dans l'arborescence des widgets directement dans le code.
Un exemple:
@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), ), ), ); }
Tous les widgets par défaut de Flutter peuvent être affichés dans le
catalogue de widgets .
Question:
Comment ajouter ou supprimer un composant dans la mise en page pendant que l'application est en cours d'exécution?
La réponse est:
Grâce à une fonction qui renverra le widget souhaité en fonction de l'état.
Différences:
Sur Android, vous pouvez faire addView () ou removeView () dans un ViewGroup. Dans Flutter, vous ne pouvez pas les widgets sont inchangés. Seul leur état peut changer.
Un exemple:
Comment changer le texte en bouton en cliquant sur FloatingActionButton.
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Question:
Comment animer des widgets?
La réponse est:
Utilisation de la classe
AnimationController , qui est la descendante de la classe abstraite
Animation <T> . En plus de démarrer l'animation, il peut la mettre en pause, revenir en arrière, l'arrêter et la jouer dans la direction opposée. Fonctionne avec
Ticker , qui signale un rafraîchissement de l'écran.
Différences:
Sur Android, vous pouvez créer des animations en XML ou animer la vue en utilisant animate (). Dans Flutter, l'animation doit être écrite en code à l'aide de AnimationController.
Information complémentaire:
Vous pouvez en savoir plus dans les
widgets Animation & Motion , le
didacticiel Animations et la
vue d'ensemble Animations .
Un exemple:
Animation en fondu du logo Flutter.
import 'package:flutter/material.dart'; void main() { runApp(FadeAppTest()); } class FadeAppTest extends StatelessWidget {
Question:
Comment utiliser
Canvas ?
La réponse est:
Android et Flutter ont la même API pour Canvas, comme ils utilisent le même moteur
Skia de bas niveau.
Différences:
Non.
Information complémentaire:
Flutter a deux classes pour dessiner sur Canvas -
CustomPaint et
CustomPainter . Le second implémente votre algorithme de rendu.
En savoir plus ici:
StackOverflowUn exemple:
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; }
Question:
Comment créer des widgets personnalisés?
La réponse est:
Composez des widgets à l'intérieur d'un (au lieu de l'héritage).
Différences:
Dans Android, nous pouvons hériter de la vue qui nous intéresse et ajouter notre propre logique. Dans Flutter, cela ressemble à un ViewGroup, seul le widget est toujours hérité de StatelessWidget ou StatefulWidget. C'est-à-dire vous devez créer un nouveau widget et l'utiliser comme l'ensemble de widgets dont vous avez besoin en tant que paramètres ou champs.
Un exemple:
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"), ); }
Intentions
Question:
Quel est l'analogue de
Intent in Flutter?
La réponse est:
Il n'est pas là. Pour naviguer entre les écrans, les classes
Navigator et
Route sont utilisées.
Pour interagir avec des composants externes (par exemple, une caméra ou un sélecteur de fichiers), vous pouvez utiliser des
plugins ou une intégration native sur chaque plate-forme. En savoir plus sur l'intégration native:
Développement de packages et de plugins .
Différences:
Flutter n'a pas d'activité et de fragment. Il existe Navigator (Navigator) et Routes (routes). L'application Flutter ressemble à une application à activité unique, où différents écrans représentent différents fragments, et FragmentManager les contrôle. Navigator est similaire au FragmentManager en principe. Il peut faire
push () ou
pop () sur l'itinéraire que vous spécifiez. La route est une sorte de fragment, mais dans Flutter, il est habituel de la comparer avec un écran ou une page.
Dans Android, nous décrivons toutes les activités entre lesquelles nous pouvons naviguer dans AndroidManifest.xml.
Flutter a deux façons:
- Décrire une carte nommée Route (MaterialApp)
- Accédez directement à Route (WidgetApp).
Un exemple:
void main() { runApp(MaterialApp( home: MyAppHome(),
Question:
Comment traiter les intentions provenant d'autres applications?
La réponse est:
Interagir avec la couche Android de l'application via le
MethodChannel .
Un exemple:
Nous écrivons intention-filtre dans 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>
Nous traitons l'intention dans MainActivity et appelons le code du Flutter via le 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);
Nous demandons des données lorsque le widget commence à être dessiné:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Question:
Quel est l'analogue de
startActivityForResult () ?
La réponse est:
Le mot-clé wait et le résultat d'une
classe Future .
Différences:
Après avoir appelé startActivityForResult () dans Android, nous devons implémenter le traitement dans onActivityResult (). Flutter n'a pas besoin d'implémenter quoi que ce soit, car la méthode du navigateur push () renvoie un objet Future.
Un exemple:
Map coordinates = await Navigator.of(context).pushNamed('/location');
Et quand nous avons obtenu les coordonnées sur l'écran '/ location', faites pop ():
Navigator.of(context).pop({"lat":43.821757,"long":-79.226392});
Async ui
Question:
Quel est l'analogue de
runOnUiThread () dans Flutter?
La réponse est:
Dart implémente un modèle d'exécution monothread qui s'exécute sur des
isolats . L'exécution asynchrone utilise async / wait, que vous connaissez peut-être avec les coroutines C #, JavaScript ou Kotlin.
Un exemple:
Répondre à la demande et renvoyer le résultat de la mise à jour de l'interface utilisateur:
loadData() async { String dataURL = "https://jsonplaceholder.typicode.com/posts"; http.Response response = await http.get(dataURL); setState(() { widgets = json.decode(response.body); }); }
Lorsque la réponse à la demande est reçue, vous devez appeler la méthode
setState () pour redessiner l'arborescence du widget avec les nouvelles données.
Un exemple:
Chargement et mise à jour des données dans 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); }); } }
Question:
Comment exécuter du code dans un thread d'arrière-plan?
La réponse est:
Comme mentionné ci-dessus - en utilisant async / wait et isolation (Isolate).
Différences:
Hors de la boîte sur Android, vous pouvez utiliser AsyncTask. Vous devez y implémenter
onPreExecute () ,
doInBackground () ,
onPostExecute () . Dans Flutter «prêt à l'emploi», il vous suffit d'utiliser asynchrone / attendre, Dart s'occupe du reste.
Un exemple:
Ici, la méthode dataLoader () est isolée. Isolément, vous pouvez exécuter des opérations lourdes telles que l'analyse de gros JSON, le chiffrement, le traitement d'image, etc.
loadData() async { ReceivePort receivePort = ReceivePort(); await Isolate.spawn(dataLoader, receivePort.sendPort);
Question:
Qu'est-
ce que l'équivalent Flutter d'
OkHttp ?
La réponse est:
Flutter a son propre
package HTTP .
Information complémentaire:
Jusqu'à présent, toutes les fonctionnalités OkHttp n'ont pas été implémentées dans le package HTTP, de nombreuses fonctionnalités manquantes sont donc abstraites et vous pouvez les implémenter vous-même si nécessaire.
Un exemple:
Pour utiliser le package HTTP, ajoutez-le en tant que dépendance dans pubspec.yaml:
dependencies: ... http: ^0.11.3+16
Pour exécuter la demande, appelez wait dans la fonction asynchrone 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); }); } }
Question:
Comment montrer les progrès?
La réponse est:
Utilisation du widget
ProgressIndicator .
Un exemple:
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); }); } }
Structure et ressources du projet
Question:
Où stocker les ressources de différentes résolutions?
La réponse est:
En actifs.
Différences:
Dans Android, les ressources ont un dossier res et ont des ressources. Flutter n'a que des atouts. Le dossier des ressources peut être situé n'importe où dans le projet, et surtout, écrivez le chemin d'accès dans le fichier pubspec.yaml.
Information complémentaire:
Comparaison des tailles de ressources graphiques dans Android et Flutter.
Flutter utilise AssetManager ou des classes spécialisées commençant par Asset pour utiliser les ressources dans le code.
Un exemple:
AssetManager:
val flutterAssetStream = assetManager.open("flutter_assets/assets/my_flutter_asset.png")
Emplacement des ressources:
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
Chemin dans le fichier pubspec.yaml:
assets: - images/my_icon.jpeg
Utilisation de
AssetImage :
return AssetImage("images/a_dot_burr.jpeg");
Utilisation directe de l'actif:
@override Widget build(BuildContext context) { return Image.asset("images/my_image.png"); }
Question:
Où stocker les cordes? Comment les localiser?
La réponse est:
Conserver dans des champs statiques. Localisez à l'aide du
package intl .
Un exemple:
class Strings { static String welcomeMessage = "Welcome To Flutter"; } Text(Strings.welcomeMessage)
Question:
Quel est l'analogue du fichier Gradle? Comment ajouter des dépendances?
La réponse est:
pubspec.yaml.
Information complémentaire:
Flutter délègue l'assemblage aux constructeurs natifs Android et iOS. Voir une liste de toutes les bibliothèques populaires pour Flutter au
Pub .
Activités et fragments
Question:
Quel est l'équivalent de l'
activité et du
fragment dans Flutter?
La réponse est:
Tout dans Flutter est des widgets. Le rôle de l'activité et des fragments pour travailler avec l'interface utilisateur est joué par les widgets. Et le rôle de la navigation, comme mentionné dans le paragraphe sur la navigation, est Navigateur et Route.
Information complémentaire:
Flutter pour les développeurs Android: comment concevoir une interface utilisateur d'activité dans Flutter .
Question:
Comment gérer les événements du cycle de vie?
La réponse est:
Utilisation de la
méthode WidgetsBinding et
didChangeAppLifecycleState () .
Information complémentaire:
Flutter utilise FlutterActivity dans le code natif et le moteur Flutter rend les changements d'état de traitement aussi discrets que possible. Mais si vous avez encore besoin de travailler selon l'état, le cycle de vie est légèrement différent:
- inactif - cette méthode est uniquement dans iOS, dans Android il n'y a pas d'analogue;
- en pause - similaire à onPause () dans Android;
- reprise - similaire à onPostResume () dans Android;
- suspension - similaire à onStop dans Android, dans iOS il n'y a pas d'analogue.
Ceci est décrit plus en détail dans la
documentation AppLifecycleStatus .
Un exemple:
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())); }
Disposition
Question:
Quel est l'analogue de
LinearLayout ?
La réponse est:
Ligne pour horizontal,
colonne pour vertical.
Information complémentaire:
Flutter pour les développeurs Android: comment concevoir LinearLayout dans Flutter?Un exemple:
@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'), ], ); }
Question:
Quel est l'équivalent de
RelativeLayout ?
La réponse est:
Widget
Stack .
Plus de détails:
StackoverflowQuestion:
Quel est l'analogue de
ScrollView ?
La réponse est:
ListView avec des widgets.
Un exemple:
@override Widget build(BuildContext context) { return ListView( children: <Widget>[ Text('Row One'), Text('Row Two'), Text('Row Three'), Text('Row Four'), ], ); }
Question:
Comment gérer les transitions entre portrait et paysage?
La réponse est:
FlutterView gère les flips si AndroidManifest.xml contient
android: configChanges = "orientation | screenSize"
Gestes et gestion des événements tactiles
Question:
Comment ajouter un écouteur onClick pour un widget dans Flutter?
La réponse est:
Si le widget prend en charge les clics, alors dans onPressed (). Sinon, alors dans onTap ().
Un exemple:
Dans onPressed ():
@override Widget build(BuildContext context) { return RaisedButton( onPressed: () { print("click"); }, child: Text("Button")); }
Dans onTap ():
class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: GestureDetector( child: FlutterLogo( size: 200.0, ), onTap: () { print("tap"); }, ), )); } }
Question:
Comment gérer d'autres gestes sur les widgets?
La réponse est:
Utilisation de
GestureDetector . Ils peuvent gérer les actions suivantes:
Appuyez sur
Appuyez deux fois
Appui long
Traînée verticale
Glissement horizontal
Un exemple:
Traitement sur Double Tap:
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(); } }, ), )); } }
Vues de liste et adaptateurs
Question:
Quel est l'analogue de
ListView dans Flutter?
La réponse est:
ListViewDifférences:
Flutter n'a pas à penser au nettoyage et à la réutilisation des éléments (c'est ce que fait ListView / RecyclerView dans Android, en utilisant le modèle ViewHolder).
Un exemple:
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Question:
Comment savoir sur quel élément on a cliqué?La réponse est:
Envelopper un élément dans un GestureDetector .Un exemple:
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Question:
Comment mettre à jour dynamiquement un ListView ?La réponse est:
Si vous avez un petit ensemble de données, cela peut être fait via setState () . Si l'ensemble de données est volumineux, alors via ListView.Builder , qui est un analogue de RecyclerView .Un exemple:
En utilisant setState () : import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
À l'aide de ListView.Builder : import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Travailler avec du texte
Question:
Comment utiliser des polices personnalisées?La réponse est:
Il vous suffit de mettre le fichier de police dans le dossier (pensez au nom vous-même) et d'indiquer le chemin d'accès à celui-ci dans pubspec.yaml.Un exemple:
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'), ), ), ); }
Question:
Comment styliser des widgets de texte?La réponse est:
Utilisation de paramètres:- la couleur;
- décoration;
- decorationColor;
- decorationStyle;
- fontFamily;
- fontSize;
- fontStyle;
- fontWeight;
- hashCode;
- height;
- inherit;
- letterSpacing;
- textBaseline;
- wordSpacing.
:
Retrieve the value of a text field .
:
hint
TextInput ?
La réponse est:
InputDecoration , .
Un exemple:
body: Center( child: TextField( decoration: InputDecoration(hintText: "This is a hint"), ) )
:
?
La réponse est:
—
InputDecoration .
Un exemple:
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Flutter
:
GPS?
La réponse est:
geolocator .
:
?
La réponse est:
image_picker .
:
Facebook?
La réponse est:
flutter_facebook_login .
:
Firebase?
La réponse est:
Firebase
Flutter first party plugins .
:
() ?
La réponse est:
Flutter EventBus . :
developing packages and plugins .
:
NDK?
La réponse est:
NDK- Flutter. Flutter .
Themes
:
(Theme) ?
La réponse est:
MaterialApp WidgetApp .
Un exemple:
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 réponse est:
Shared_Preferences plugin ( NSUserDefaults iOS ).
Un exemple:
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 réponse est:
SQFlite .
Notifications
:
push-?
La réponse est:
Firebase_Messaging .
Conclusion
. , , . « » . «-» . , ? 2016 Kotlin, - 2017. , , . , .
2016 Flutter Dart. , 2018 . . ! , , , . ( Google Fuchsia , , , Flutter ). — ! , — . C’est tout pour moi. Google Play!