Nous continuons l'interprétation laconique de la
documentation officielle de Flutter dans un format de questions et réponses. Il s'agit de la troisième partie et elle sera plus utile aux développeurs React Native. Dans cette interprétation, vous pouvez trouver des réponses aux questions fréquemment posées, ainsi que déterminer par vous-même combien d'efforts vous devez faire pour passer d'un cadre multiplateforme à un autre.

Si ces informations ne suffisent pas ou si vous avez de l'expérience en développement natif pour une plate-forme spécifique, je vous recommande de regarder dans d'autres parties:
Flutter. Partie 1. Pour les développeurs AndroidFlutter. Partie 2. Pour les développeurs iOSFlutter. Partie 3. Pour les développeurs natifs de ReactFlutter. Partie 4. Pour les développeurs Web
Flutter. Partie 5. Pour les développeurs Xamarin.Forms
Contenu:
- Un peu sur Dart
- Les bases
- Structure et ressources du projet
- Vues
- Disposition
- Stylisation
- Gestion de l'État
- Stockage local
- La navigation
- Gestes et gestion des événements tactiles
- Demandes HTTP
- Formulaire de saisie
- Code spécifique à la plateforme
- Débogage
- L'animation
- Équivalents de composants
- Plugins Flutter
Un peu sur Dart
Question:
Où est le point d'entrée?
La réponse est:
Fonction
main()
.
Différences:
JavaScript n'a pas de point d'entrée prédéfini; il peut s'agir de n'importe quelle fonction définie par le développeur. Dans Dart, ce n'est que
main()
.
Question:
Comment sortir sur la console?
La réponse est:
Utilisation de la fonction
print()
.
Différences:
En JavaScript, la sortie de la console se fait à l'aide de
console.log()
.
Un exemple:
print('Hello world!');
Question:
Comment créer et affecter des variables / champs?
La réponse est:
Dart prend en charge la frappe dynamique et forte. Par conséquent, les variables / champs peuvent être créés dans n'importe quel type de saisie qui vous convient. L'affectation se fait via single =.
Différences:
La frappe forte n'est pas prise en charge en JavaScript.
Information complémentaire:
Plus de détails ici.Un exemple:
String name = 'dart';
Question:
Quelle est la valeur par défaut d'une variable / champ?
La réponse est:
null
Différences:
JavaScript n'est
undefined
par défaut.
Information complémentaire:
Plus de détails ici.Question:
Comment vérifier une valeur pour
null
ou pour 0?
La réponse est:
Utilisation de la vérification explicite
==
.
Différences:
En JavaScript, dans le cadre de la vérification
if
, le numéro 1 ou tout
non-null
objet
non-null
sera équivalent à
true
. Dans Dart, seule une valeur booléenne
true
équivalente à
true
.
Un exemple:
var myNull = null; if (myNull == null) { print('use "== null" to check null'); } var zero = 0; if (zero == 0) { print('use "== 0" to check zero'); }
Question:
Comment déclarer des fonctions?
La réponse est:
Dans Dart, les fonctions, comme les champs, peuvent être avec un typage dynamique ou fort de la valeur de retour. Les types typés dynamiquement sont déclarés simplement par le nom de la fonction et éventuellement par les paramètres, tandis que ceux fortement typés au début ont toujours un type de retour.
Différences:
En JavaScript, une fonction est déclarée avec le mot clé
function
, suivi d'un nom et éventuellement de paramètres.
Information complémentaire:
Plus de détails ici.Un exemple:
fn() { return true; }
Question:
Quel est l'équivalent de
Promise ?
La réponse est:
L'avenirInformation complémentaire:
Dart, comme JavaScript, prend en charge l'exécution monothread.
Future in Dart a la même signification que
Promise in React Native.
Plus de détails ici. .
Un exemple:
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)); }
Question:
Quel est l'analogue de
async
et
await
?
La réponse est:
async
et
await
Différences:
En JavaScript, les fonctions asynchrones renvoient
Promise , dans Dart, elles renvoient
Future . wait attend de manière synchrone le résultat de l'appel d'une fonction asynchrone.
Information complémentaire:
Plus de détails ici.Un exemple:
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); } }
Les bases
Question:
Comment créer un projet d'application sur Flutter?
La réponse est:
- Utilisation de l'EDI avec les plugins Flutter et Dart installés.
- Utilisation de la commande
flutter create {projectname}
.
Différences:
Pour créer un projet dans React Native, utilisez la commande
create-react-native-app {projectname}
.
Information complémentaire:
Plus de détails ici.Question:
Comment démarrer l'application?
La réponse est:
- Utilisation de la fonction d'exécution dans l'EDI avec les plugins Flutter et Dart installés.
- Utilisation de la commande
flutter run
.
Différences:
React Native utilise les commandes
npm run
ou
yarn run
pour lancer l'application.
Question:
Comment importer des widgets?
La réponse est:
Dans Flutter, tous les widgets sont divisés en packages, il est donc important d'importer un package pour utiliser ses widgets.
Différences:
Dans React Native, vous devez importer chaque widget.
Un exemple:
import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter/my_widgets.dart';
Question:
Comment utiliser les widgets et l'imbrication pour construire une arborescence de widgets?
La réponse est:
Dans Flutter, presque tout est un widget. Même l'objet d'application est un widget. Chaque widget peut être imbriqué dans le parent. En combinant des widgets, vous créez une hiérarchie appelée l'arborescence des widgets. C'est elle qui se transforme plus tard en affichage à l'écran.
Un exemple:
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'), ), ), ); } }
Question:
Comment créer des composants réutilisables?
La réponse est:
Dans Flutter, vous pouvez créer une classe de widgets et la réutiliser. Les paramètres utilisés sont des champs de classe.
Différences:
Dans React Native, pour modifier les paramètres d'un élément réutilisé, vous devez les marquer comme accessoires.
Information complémentaire:
Les paramètres dans le constructeur peuvent être déclarés de deux manières: par une énumération régulière et facultative, en utilisant des accolades
{}
. Des différences se produisent lors de l'utilisation de paramètres pour appeler le constructeur.
Dans l'énumération habituelle, tous les paramètres sont requis et lorsque vous appelez le constructeur, vous ne pouvez pas spécifier quel paramètre particulier est transmis, car ils sont dus à la commande.
Avec l'option, vous pouvez utiliser n'importe quel ordre dans lequel les paramètres sont transmis, mais vous devez spécifier quel paramètre spécifique est transmis ou ne pas les transmettre du tout. Pour marquer un paramètre facultatif comme requis, utilisez l'annotation
@required
.
Un exemple:
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, ), ], ) ); } } ...
Structure et ressources du projet
Question:
Par où commencer à écrire du code?
La réponse est:
Dans
{projectname}/lib/main.dart
.
Question:
Quelle est la structure des fichiers dans un projet Flutter?
La réponse est:
┬ └ projectname ┬ ├ android - Android . ├ build - iOS Android . ├ ios - iOS . ├ lib - Dart . ┬ └ src - Contains additional source files. └ main.dart - . ├ test - . └ pubspec.yaml - . package.json React Native.
Question:
Où stocker les ressources et les actifs et comment les utiliser?
La réponse est:
Les liens vers les ressources et les dépendances du projet sont stockés dans le fichier
pubspec.yaml
. En fait, vous pouvez les placer dans n'importe quel dossier à l'intérieur de
lib
, surtout, spécifiez le chemin d'accès à eux dans
pubspec.yaml
. Vous pouvez les utiliser dans un projet en utilisant des widgets spécialisés, par exemple
AssetImage , ou directement en utilisant
AssetBundle .
Information complémentaire:
Plus de détails ici.Un exemple:
Déclaration des actifs dans
pubspec.yaml
flutter: assets: - assets/my_icon.png - assets/background.png
Utilisation dans le code
image: AssetImage('assets/background.png'),
Question:
Comment télécharger des images depuis le réseau?
La réponse est:
Utilisation d'
Image.network .
Un exemple:
body: Image.network( 'https://flutter.io/images/owl.jpg',
Question:
Comment connecter des packages et plugins tiers?
La réponse est:
Utilisation des
dependencies
dans
pubspec.yaml
.
Différences:
React Native utilise les commandes
yarn add {package-name}
ou
npm install --save {package-name}
pour ajouter des dépendances.
Information complémentaire:
Utilisation de packagesDéveloppement de packages et de pluginsPlugins populaires pour FlutterUn exemple:
dependencies: flutter: sdk: flutter google_sign_in: ^3.0.3
Vues
Question:
Quel est l'équivalent d'un conteneur
View ?
La réponse est:
Tous les widgets de base pour la mise en page, par exemple
Conteneur ,
Colonne ,
Ligne et
Centre .
Information complémentaire:
Plus de détails ici.Question:
Quel est l'analogue de
FlatList ou
SelectionList ?
La réponse est:
ListviewUn exemple:
var data = [ ... ]; ListView.builder( itemCount: data.length, itemBuilder: (context, int index) { return Text( data[index], ); }, )
Question:
Comment utiliser Canvas?
La réponse est:
Utilisation des
classes CustomPaint et
CustomPainter .
Différences:
Dans React Native, il n'y a aucun moyen de dessiner en utilisant Canvas hors de la boîte. Il existe des plugins tiers, par exemple
react-native-canvas
.
Un exemple:
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(), ), ); } }
Disposition
Question:
Comment utiliser les widgets pour décrire les propriétés de mise en page?
La réponse est:
Flutter utilise des widgets spécialisés pour les propriétés de mise en page, par exemple:
Colonne ,
ligne ,
rembourrage ,
alignement ,
pile .
Différences:
Dans React Native, le plus souvent, les propriétés de mise en page peuvent être définies à l'aide d'
props
.
Information complémentaire:
Liste complète des widgetsQuestion:
Comment positionner les widgets dans la mise en page?
La réponse est:
Pour un positionnement absolu, utilisez le widget
Stack . Pour le parent - divers widgets et leurs combinaisons, qui peuvent être trouvés
ici .
Un exemple:
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'), ), ], )
Stylisation
Question:
Comment styliser les composants?
La réponse est:
Le plus souvent, les widgets ont une propriété de
style
.
Différences:
React Native utilise
stylesheets.create
pour le style.
Un exemple:
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) ), ], ), )
Question:
Comment utiliser les icônes et les couleurs?
La réponse est:
Utilisation des classes
Icônes et
Couleurs .
Différences:
React Native ne prend pas en charge les icônes hors de la boîte.
Un exemple:
Icônes
Icon(Icons.lightbulb_outline, color: Colors.redAccent)
Les couleurs
class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Sample App', theme: ThemeData( primarySwatch: Colors.blue, textSelectionColor: Colors.red ), home: SampleAppPage(), ); } }
Question:
Comment personnaliser le thème stylistique de l'application?
La réponse est:
Utilisation de la classe
ThemeData .
Différences:
Dans React Native, un thème commun est configuré via des
stylesheets
.
Un exemple:
@override Widget build(BuildContext context) { return Theme( data: ThemeData( primaryColor: Colors.cyan, brightness: brightness, ), child: Scaffold( backgroundColor: Theme.of(context).primaryColor, ... ... ), ); }
Gestion de l'État
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 est génial! import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget {
Stockage local
Question:
Comment stocker
key-value
données de
key-value
dans une application?
La réponse est:
Utilisation du plugin
shared_preferences .
Différences:
React Native utilise
AsyncStorage .
Un exemple:
Dépendance
dependencies: flutter: sdk: flutter shared_preferences: ^0.4.3
Utiliser
SharedPreferences prefs = await SharedPreferences.getInstance(); _counter = prefs.getInt('counter'); prefs.setInt('counter', ++_counter); setState(() { _counter = _counter; });
Question:
Comment stocker des données complexes?
La réponse est:
Utilisation de plugins de base de données, par exemple
sqflite ou
hive .
La navigation
Question:
Comment naviguer entre les écrans?
La réponse est:
Pour naviguer entre les écrans, les classes
Navigator et
Route sont utilisées.
Différences:
React Native utilise
StackNavigator ,
TabNavigator et
DrawerNavigator .
Flutter a deux méthodes de navigation:
- Décrire une carte avec des noms de route
- Accédez directement à Route .
Navigator peut faire
pousser () ou
pop () vers l'itinéraire que vous spécifiez.
Un exemple:
void main() { runApp(CupertinoApp( home: MyAppHome(),
Question:
Comment utiliser la navigation par onglets?
La réponse est:
Utilisation de classes:
TabController ,
TabBar ,
Tab et
TabBarView .
Différences:
React Native utilise
createBottomTabNavigator et TabNavigation .
Information complémentaire:
Plus de détails ici. .
Un exemple:
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, ) ); } }
Question:
Comment utiliser la navigation dans les tiroirs?
La réponse est:
Utilisation de la classe
Drawer .
Différences:
React Native utilise
createDrawerNavigator et DrawerNavigation .
Un exemple:
@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(), ); }
Gestes et gestion des événements tactiles
Question:
Comment gérer un clic?
La réponse est:
Si le widget prend en charge les clics, alors dans
onPressed()
. Sinon, utilisez le widget
GestureDetector .
Différences:
React Native utilise
PanResponder ou
Touchable pour cela.
Un exemple:
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'); }, );
Demandes HTTP
Question:
Comment obtenir des données à partir de requêtes API?
La réponse est:
Utilisation d'un
plugin http .
Différences:
React Native utilise l'
fetch API
.
Un exemple:
Connexion plugin
dependencies: flutter: sdk: flutter http: <latest_version>
Récupération de données
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; }); }
Formulaire de saisie
Question:
Quels widgets utiliser pour la saisie?
La réponse est:
TextField en conjonction avec
TextEditingController ou
TextFormField .
Différences:
React Native utilise
TextInput .
TextFormField diffère de
TextField par sa validation intégrée et sa logique de stockage des valeurs dans les champs.
Un exemple:
Champ de texte
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'), ) ); } }
Code spécifique à la plateforme
Question:
Comment déterminer sur quelle plateforme s'exécute le code?
La réponse est:
Utilisation de la classe de champ
Platform dans
Theme ou de la classe
Platform .
Un exemple:
Champ de plate-forme
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 plate-forme
if (Platform.isIOS) { return 'iOS'; } else if (Platform.isAndroid) { return 'android'; } else if (Platform.isFuchsia) { return 'fuchsia'; } else { return 'not recognised '; }
Question:
Comment appeler du code de plateforme natif?
La réponse est:
Via
MethodChannel .
Information complémentaire:
Plus de détails ici. .
Débogage
Question:
Quels sont les outils pour déboguer l'application?
La réponse est:
DevToolsQuestion:
Comment faire
hot reload
?
La réponse est:
Si l'application a été lancée à partir d'IntelliJ IDE ou d'Android Studio,
⌘s/ctrl-s
alors
⌘s/ctrl-s
ou cliquez sur l'icône de
hot reload
. Si démarré à partir du terminal, puis en entrant la lettre
r
.
Différences:
React Native utilise
⌘R/Ctrl+R
pour les émulateurs iOS, double
R
pour Android.
Question:
Comment accéder au menu développeur dans l'application?
La réponse est:
Si le lancement était à partir de l'IDE, puis à l'aide des outils IDE. Si depuis la console, utilisez h.
Différences:
React Native utilise
⌘D/Ctrl+D
pour les émulateurs iOS et
⌘M/Ctrl+M
pour Android.
Information complémentaire:
Liste complète des équipes
L'animation
Question:
Qu'est-ce qui est utilisé pour l'animation?
La réponse est:
Animation et
AnimationController .
Différences:
React Native utilise l'
Animation API
.
Information complémentaire:
Plus de détails ici.Question:
Comment ajouter une animation de
fade-in
simple?
La réponse est:
Utilisation de
FadeTransition .
Un exemple:
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(); } }
Question:
Comment ajouter une animation de balayage à la liste des éléments?
La réponse est:
Utilisation de
Rejetable .
Un exemple:
child: Dismissible( key: key, onDismissed: (DismissDirection dir) { cards.removeLast(); }, child: Container( ... ), ),
Équivalents de composants
Question:
Quels sont les équivalents de Flutter par rapport à React Native?
La réponse est:
Plugins Flutter
Question:
Comment accéder au GPS?
La réponse est:
Utilisation du plugin
geolocator .
Question:
Comment accéder à la caméra?
La réponse est:
Utilisation du plugin
image_picker .
Question:
Comment se connecter via Facebook?
La réponse est:
Utilisation du plugin
flutter_facebook_login .
Question:
Comment utiliser Firebase?
La réponse est:
Firebase prend en charge
les plugins Flutter propriétaires :
Voici peut-être les réponses aux questions de base. J'espère que mon interprétation vous a été utile, et si vous n'écrivez pas encore sur Flutter, alors pensez-y au moins. Cela signifie qu'il peut y avoir un ajout à l'étagère Flutter des développeurs, et ensemble, nous ferons du monde un meilleur endroit grâce au prisme d'applications développées pratiques et rapides! Oui, React ne cassera pas votre Native!