0% ont trouvé ce document utile (0 vote)
10 vues10 pages

Questions Entretien Flutter

Le document présente des questions d'entretien technique sur le développement mobile avec Flutter, abordant des concepts clés tels que la différence entre StatelessWidget et StatefulWidget, le cycle de vie d'un StatefulWidget, et la gestion de la navigation entre les écrans. Il explique également des notions comme le BuildContext, les appels API asynchrones, et la configuration du fichier pubspec.yaml. Enfin, il clarifie les différences entre les widgets Container, Padding et SizedBox, ainsi que les mécanismes de hot reload et hot restart.

Transféré par

ahmedborgi64
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
10 vues10 pages

Questions Entretien Flutter

Le document présente des questions d'entretien technique sur le développement mobile avec Flutter, abordant des concepts clés tels que la différence entre StatelessWidget et StatefulWidget, le cycle de vie d'un StatefulWidget, et la gestion de la navigation entre les écrans. Il explique également des notions comme le BuildContext, les appels API asynchrones, et la configuration du fichier pubspec.yaml. Enfin, il clarifie les différences entre les widgets Container, Padding et SizedBox, ainsi que les mécanismes de hot reload et hot restart.

Transféré par

ahmedborgi64
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Questions d'Entretien Technique

Développement Mobile - Flutter

Date: 23/12/2025

1. Quelle est la différence entre StatelessWidget et StatefulWidget ?


Réponse :

StatelessWidget :
• Widget immuable qui ne change pas d'état
• Reconstruit uniquement lorsque ses paramètres externes changent
• Plus léger et plus performant
• Utilisé pour l'affichage de contenu statique
• Exemple : Text, Icon, Image

StatefulWidget :
• Widget qui peut changer d'état dynamiquement
• Possède un objet State qui conserve les données modifiables
• Peut se reconstruire via setState()
• Utilisé pour du contenu interactif ou changeant
• Exemple : Checkbox, TextField, animations

Exemple de code :

// StatelessWidget class MyStatelessWidget extends StatelessWidget { @override


Widget build(BuildContext context) { return Text('Je ne change pas'); } } //
StatefulWidget class MyStatefulWidget extends StatefulWidget { @override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState(); } class
_MyStatefulWidgetState extends State<MyStatefulWidget> { int counter = 0; @override
Widget build(BuildContext context) { return Column( children: [ Text('Counter:
$counter'), ElevatedButton( onPressed: () => setState(() => counter++), child:
Text('Increment'), ), ], ); } }

2. Qu'est-ce que le widget tree et comment Flutter gère-t-il le rendu ?


Réponse :

Le Widget Tree (Arbre de Widgets) :


• Structure hiérarchique de tous les widgets de l'application
• Chaque widget est un nœud dans l'arbre
• Les widgets enfants sont contenus dans leurs parents
Processus de rendu Flutter :

1. Widget Tree : Configuration immuable de l'UI


2. Element Tree : Instance des widgets, gère le cycle de vie
3. Render Tree : Objets qui effectuent le rendu réel

Mécanisme de rebuild :
• Flutter compare les anciens et nouveaux widgets
• Seuls les widgets modifiés sont reconstruits (rebuild)
• Optimisation via les "keys" pour identifier les widgets
• Le framework minimise les opérations coûteuses

Avantages :
• Performance élevée (60 fps)
• Rendu efficace avec reconciliation intelligente
• Hot reload rapide grâce à cette architecture

3. Expliquez le cycle de vie d'un StatefulWidget


Réponse :

Phases du cycle de vie :

1. createState()
• Premier appel lors de la création du widget
• Crée l'objet State associé

2. initState()
• Appelé une seule fois après la création
• Initialisation des variables, abonnements, controllers
• Ne peut pas utiliser BuildContext ici pour certaines opérations

3. didChangeDependencies()
• Appelé après initState() et quand les dépendances changent
• Accès au BuildContext disponible

4. build()
• Appelé à chaque fois que le widget doit être rendu
• Retourne l'arbre de widgets à afficher
• Appelé après setState()

5. didUpdateWidget()
• Appelé quand le widget parent se reconstruit avec une nouvelle configuration
• Permet de comparer l'ancien et le nouveau widget

6. setState()
• Notifie Flutter qu'il y a un changement d'état
• Déclenche un nouveau build()

7. deactivate()
• Appelé quand le widget est retiré de l'arbre temporairement

8. dispose()
• Appelé quand le widget est définitivement retiré
• Libération des ressources (controllers, subscriptions, listeners)

class MyWidget extends StatefulWidget { @override _MyWidgetState createState() =>


_MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { @override void
initState() { [Link](); print('1. initState - Initialisation'); }
@override void didChangeDependencies() { [Link](); print('2.
didChangeDependencies'); } @override Widget build(BuildContext context) { print('3.
build - Construction du widget'); return Container(); } @override void
didUpdateWidget(MyWidget oldWidget) { [Link](oldWidget); print('4.
didUpdateWidget'); } @override void dispose() { print('5. dispose - Nettoyage');
[Link](); } }

4. Quelle est la différence entre hot reload et hot restart ?


Réponse :

Hot Reload :
• Injecte les fichiers modifiés dans la Dart VM
• Préserve l'état de l'application (variables, données)
• Reconstruction rapide de l'UI uniquement
• Ne ré-exécute pas la fonction main()
• Idéal pour les changements d'UI
• Temps : ~1-2 secondes
• Raccourci : r dans le terminal, ou Ctrl+\ (VSCode)

Limitations du Hot Reload :


• Ne fonctionne pas pour les changements de structure de classe
• Ne recharge pas les variables globales ou statiques
• Ne s'applique pas aux changements d'énumérations

Hot Restart :
• Redémarre complètement l'application
• Perd tout l'état de l'application
• Ré-exécute la fonction main()
• Réinitialise toutes les variables
• Nécessaire pour les changements structurels
• Temps : ~5-10 secondes
• Raccourci : R dans le terminal, ou Ctrl+Shift+\ (VSCode)

Quand utiliser Hot Restart :


• Modifications de la fonction main()
• Changements dans les variables globales
• Modifications d'énumérations
• Ajout/suppression de fichiers
• Changements dans les assets ([Link])

5. Comment gérez-vous la navigation entre les écrans dans Flutter ?


Réponse :

Méthode 1 : Navigation basique avec Navigator

// Navigation vers un écran [Link]( context, MaterialPageRoute(builder:


(context) => SecondScreen()), ); // Retour à l'écran précédent
[Link](context); // Retour avec une valeur [Link](context,
'Résultat'); // Navigation avec remplacement [Link]( context,
MaterialPageRoute(builder: (context) => NewScreen()), );

Méthode 2 : Routes nommées

// Dans MaterialApp MaterialApp( initialRoute: '/', routes: { '/': (context) =>


HomeScreen(), '/second': (context) => SecondScreen(), '/third': (context) =>
ThirdScreen(), }, ); // Navigation avec route nommée [Link](context,
'/second'); // Avec arguments [Link]( context, '/second', arguments:
{'id': 123, 'name': 'Flutter'}, ); // Récupérer les arguments final args =
[Link](context)!.[Link] as Map;

Méthode 3 : Routes générées (recommandé pour grandes apps)

MaterialApp( onGenerateRoute: (settings) { if ([Link] == '/second') { final


args = [Link] as Map; return MaterialPageRoute( builder: (context) =>
SecondScreen(data: args), ); } return null; }, );

Méthodes avancées :
• pushAndRemoveUntil() : Navigation avec suppression de l'historique
• popUntil() : Retour jusqu'à une route spécifique
• canPop() : Vérifier s'il est possible de revenir en arrière
• Navigator 2.0 : Pour des besoins avancés (deep linking, web)

Packages populaires :
• go_router : Navigation déclarative moderne
• auto_route : Génération automatique de routes
• beamer : Navigation avancée avec support web
6. Qu'est-ce que le BuildContext et pourquoi est-il important ?
Réponse :

Définition :
• Référence à l'emplacement d'un widget dans l'arbre de widgets
• Handle vers l'arbre, permettant de naviguer dans la hiérarchie
• Chaque widget possède son propre BuildContext

Utilisations principales :

1. Accès au Theme :

final theme = [Link](context); final primaryColor = [Link]; final


textTheme = [Link];

2. Navigation :

[Link](context).push(...); [Link](context).pop();

3. Affichage de dialogs et snackbars :

[Link](context).showSnackBar( SnackBar(content: Text('Message')), );


showDialog( context: context, builder: (context) => AlertDialog(...), );

4. Accès aux dimensions de l'écran :

final size = [Link](context).size; final width = [Link]; final height =


[Link];

5. Localisation :

final locale = [Link](context);

Important :
• Le context doit appartenir à un widget sous celui qui fournit les données
• Erreur fréquente : utiliser le context du Scaffold pour afficher un SnackBar

Solution avec Builder :

Scaffold( body: Builder( builder: (BuildContext context) { return TextButton(


onPressed: () { [Link](context).showSnackBar( SnackBar(content:
Text('OK!')), ); }, child: Text('Show SnackBar'), ); }, ), );

7. Quelle est la différence entre MainAxisAlignment et


CrossAxisAlignment ?
Réponse :

Ces propriétés contrôlent l'alignement des enfants dans les widgets Row et Column.

MainAxisAlignment (Axe principal) :

• Pour Column : Axe vertical (haut → bas)


• Pour Row : Axe horizontal (gauche → droite)

Valeurs disponibles :
• start : Début de l'axe
• end : Fin de l'axe
• center : Centre
• spaceBetween : Espace égal entre les éléments
• spaceAround : Espace égal autour de chaque élément
• spaceEvenly : Espace égal partout (avant, entre, après)

CrossAxisAlignment (Axe perpendiculaire) :

• Pour Column : Axe horizontal


• Pour Row : Axe vertical

Valeurs disponibles :
• start : Début de l'axe perpendiculaire
• end : Fin de l'axe perpendiculaire
• center : Centre
• stretch : Étire les enfants pour remplir l'axe
• baseline : Aligne sur la ligne de base du texte

Exemples :

// Column Column( mainAxisAlignment: [Link], // Vertical


crossAxisAlignment: [Link], // Horizontal children: [
Text('Premier'), Text('Deuxième'), Text('Troisième'), ], ) // Row Row(
mainAxisAlignment: [Link], // Horizontal crossAxisAlignment:
[Link], // Vertical children: [ Icon([Link]),
Icon([Link]), Icon([Link]), ], )

8. Comment gérez-vous les appels API asynchrones dans Flutter ?


Réponse :

Méthode 1 : async/await avec Future

import 'dart:convert'; import 'package:http/[Link]' as http; // Fonction


asynchrone Future<List<User>> fetchUsers() async { final response = await [Link](
[Link]('[Link] ); if ([Link] == 200) {
List data = [Link]([Link]); return [Link]((json) =>
[Link](json)).toList(); } else { throw Exception('Erreur de chargement'); }
} // Utilisation dans un widget class UserList extends StatefulWidget { @override
_UserListState createState() => _UserListState(); } class _UserListState extends
State<UserList> { late Future<List<User>> futureUsers; @override void initState() {
[Link](); futureUsers = fetchUsers(); } @override Widget
build(BuildContext context) { return Scaffold( body: FutureBuilder<List<User>>(
future: futureUsers, builder: (context, snapshot) { if ([Link]) { return
[Link]( itemCount: [Link]!.length, itemBuilder: (context, index) {
return ListTile( title: Text([Link]![index].name), ); }, ); } else if
([Link]) { return Center(child: Text('Erreur: \${[Link]}')); }
return Center(child: CircularProgressIndicator()); }, ), ); } }

Méthode 2 : Gestion manuelle avec setState

class DataWidget extends StatefulWidget { @override _DataWidgetState createState()


=> _DataWidgetState(); } class _DataWidgetState extends State<DataWidget> {
List<User> users = []; bool isLoading = true; String? error; @override void
initState() { [Link](); loadData(); } Future<void> loadData() async {
setState(() { isLoading = true; error = null; }); try { final data = await
fetchUsers(); setState(() { users = data; isLoading = false; }); } catch (e) {
setState(() { error = [Link](); isLoading = false; }); } } @override Widget
build(BuildContext context) { if (isLoading) { return CircularProgressIndicator();
} if (error != null) { return Text('Erreur: $error'); } return [Link](
itemCount: [Link], itemBuilder: (context, index) { return ListTile(title:
Text(users[index].name)); }, ); } }

Méthode 3 : StreamBuilder pour données en temps réel

Stream<List<Message>> getMessagesStream() { return


[Link](Duration(seconds: 5), (_) { return fetchMessages();
}).asyncMap((future) => future); } // Dans le widget StreamBuilder<List<Message>>(
stream: getMessagesStream(), builder: (context, snapshot) { if ([Link]) {
return ListView( children: [Link]!.map((msg) => Text([Link])
).toList(), ); } return CircularProgressIndicator(); }, )

Bonnes pratiques :
• Toujours gérer les 3 états : loading, success, error
• Utiliser try-catch pour capturer les erreurs
• Annuler les requêtes si le widget est disposed
• Mettre en cache les résultats quand possible
• Utiliser des packages comme dio pour des fonctionnalités avancées
• Provider/Riverpod/Bloc pour la gestion d'état complexe

9. Qu'est-ce que [Link] et à quoi sert-il ?


Réponse :

Définition :
Le fichier [Link] est le fichier de configuration principal d'un projet Flutter/Dart. Il définit
les métadonnées du projet et ses dépendances.

Contenu principal :

1. Informations du projet :

name: mon_application description: Une application Flutter incroyable version:


1.0.0+1 publish_to: 'none' environment: sdk: '>=3.0.0 <4.0.0'
2. Dépendances (packages) :

dependencies: flutter: sdk: flutter # Packages externes http: ^1.1.0 provider:


^6.0.5 shared_preferences: ^2.2.0 dev_dependencies: flutter_test: sdk: flutter
flutter_lints: ^2.0.0

3. Assets (images, fonts, fichiers) :

flutter: uses-material-design: true # Images assets: - assets/images/ -


assets/images/[Link] - assets/data/[Link] # Polices personnalisées fonts: -
family: Roboto fonts: - asset: fonts/[Link] - asset:
fonts/[Link] weight: 700 - family: CustomFont fonts: - asset:
fonts/[Link]

4. Configuration Flutter :

flutter: # Activer Material Design uses-material-design: true # Générer des


fichiers de localisation generate: true

Commandes importantes :

• flutter pub get : Télécharger les dépendances


• flutter pub upgrade : Mettre à jour les packages
• flutter pub outdated : Voir les packages obsolètes
• flutter pub add [package] : Ajouter une dépendance
• flutter pub remove [package] : Supprimer une dépendance

Version des packages :


• ^1.2.3 : Compatible avec 1.x.x (≥1.2.3 <2.0.0)
• 1.2.3 : Version exacte uniquement
• >=1.2.3 <2.0.0 : Plage de versions
• any : N'importe quelle version (déconseillé)

Bonnes pratiques :
• Toujours spécifier des versions pour les dépendances
• Utiliser [Link] pour garantir la reproductibilité
• Ne pas commiter [Link] pour les packages
• Organiser les assets dans des dossiers dédiés
• Vérifier régulièrement les mises à jour de sécurité

10. Expliquez la différence entre Container, Padding et SizedBox


Réponse :

Ces trois widgets sont utilisés pour la mise en page, mais ont des objectifs différents.

1. Container - Le plus polyvalent

Fonctionnalités :
• Padding (espace interne)
• Margin (espace externe)
• Width et Height
• Color et Decoration (bordures, ombres, gradients)
• Alignment
• Transform (rotation, scale)

Exemple :

Container( width: 200, height: 100, padding: [Link](16), margin:


[Link](vertical: 8), decoration: BoxDecoration( color: [Link],
borderRadius: [Link](12), boxShadow: [ BoxShadow( color:
[Link](0.5), spreadRadius: 2, blurRadius: 5, offset: Offset(0, 3),
), ], ), child: Text('Hello', style: TextStyle(color: [Link])), )

2. Padding - Uniquement pour l'espacement interne

Fonctionnalités :
• Ajoute uniquement du padding autour de l'enfant
• Plus léger que Container si on a besoin que de padding
• Pas de decoration, color, ou autres propriétés

Exemple :

Padding( padding: [Link](16), child: Text('Texte avec espacement'), ) //


Différents types de padding Padding( padding: [Link](left: 10, top: 20),
child: Widget(), ) Padding( padding: [Link](horizontal: 16, vertical:
8), child: Widget(), )

3. SizedBox - Pour les dimensions fixes

Fonctionnalités :
• Définit une taille fixe (width, height)
• Très performant pour créer des espaces vides
• Peut contenir un enfant ou être vide
• Plus léger que Container pour les espaces

Exemples :

// Créer un espace vertical SizedBox(height: 20) // Créer un espace horizontal


SizedBox(width: 10) // Forcer une taille spécifique pour un widget SizedBox( width:
150, height: 50, child: ElevatedButton( onPressed: () {}, child: Text('Bouton'), ),
) // Prendre toute la largeur/hauteur disponible [Link]( child:
Container(color: [Link]), ) // Réduire à la taille minimale [Link]()

Comparaison et quand utiliser chaque widget :

Utilisez Container quand :


• Vous avez besoin de décoration (couleur, bordure, ombre)
• Vous voulez combiner padding ET margin
• Vous avez besoin d'alignment ou de transform
• C'est un élément visuel avec plusieurs propriétés

Utilisez Padding quand :


• Vous avez uniquement besoin d'espace interne
• Vous voulez un code plus lisible et explicite
• Performance légèrement meilleure que Container

Utilisez SizedBox quand :


• Vous créez des espaces entre widgets (SizedBox(height: 20))
• Vous forcez une taille fixe pour un widget
• Vous voulez le widget le plus léger possible
• Vous créez un widget invisible ([Link]())

Exemple de comparaison :

// Avec Container (plus lourd mais plus de fonctionnalités) Container( width: 100,
height: 100, padding: [Link](8), decoration: BoxDecoration(color:
[Link]), child: Text('Hello'), ) // Avec Padding + SizedBox (plus léger)
SizedBox( width: 100, height: 100, child: ColoredBox( color: [Link], child:
Padding( padding: [Link](8), child: Text('Hello'), ), ), ) // Pour les
espaces (utilisez TOUJOURS SizedBox) Column( children: [ Text('Premier'),
SizedBox(height: 16), // ✓ Bon Text('Deuxième'), Container(height: 16), // ✗
Mauvais (trop lourd) ], )

________________________________________________________________________________

Document généré pour l'entretien technique Flutter

Vous aimerez peut-être aussi