flutter-build-responsive-layout

Utilisez `LayoutBuilder`, `MediaQuery`, ou `Expanded/Flexible` pour créer une mise en page qui s'adapte à différentes tailles d'écran. Utilisez ceci lorsque vous avez besoin que l'interface utilisateur s'affiche correctement sur les appareils mobiles et les facteurs de forme tablette/bureau.

npx skills add https://github.com/flutter/skills --skill flutter-build-responsive-layout

Implémenter des Mises en Page Adaptatives

Contenu

Directives de Mesure de l'Espace

Déterminez l'espace disponible avec précision pour assurer que les mises en page s'adaptent à la fenêtre de l'application, et non seulement à l'appareil physique.

  • Utilisez MediaQuery.sizeOf(context) pour obtenir la taille de toute la fenêtre de l'application.
  • Utilisez LayoutBuilder pour prendre des décisions de mise en page en fonction de l'espace alloué au widget parent. Évaluez constraints.maxWidth pour déterminer l'arborescence de widgets appropriée à retourner.
  • N'utilisez pas MediaQuery.orientationOf ou OrientationBuilder près du sommet de l'arborescence des widgets pour changer de mises en page. L'orientation de l'appareil ne reflète pas avec précision l'espace disponible dans la fenêtre de l'application.
  • Ne vérifiez pas les types de matériel (par exemple, « téléphone » par rapport à « tablette »). Les applications Flutter s'exécutent dans des fenêtres redimensionnables, des modes multi-fenêtres et en incrustation. Basez toutes les décisions de mise en page strictement sur l'espace de fenêtre disponible.

Dimensionnement des Widgets et Contraintes

Comprenez et appliquez la règle de mise en page principale de Flutter : Les contraintes descendent. Les tailles remontent. Le parent définit la position.

  • Distribuer l'Espace : Utilisez Expanded et Flexible dans les widgets Row, Column ou Flex.
    • Utilisez Expanded pour forcer un enfant à remplir tout l'espace disponible restant (équivalent à Flexible avec fit: FlexFit.tight et un facteur flex de 1,0).
    • Utilisez Flexible pour permettre à un enfant de se dimensionner jusqu'à une limite spécifique tout en s'agrandissant/se rétrécissant. Utilisez le facteur flex pour définir le rapport de consommation d'espace entre les frères et sœurs.
  • Contraindre la Largeur : Empêchez les widgets de consommer tout l'espace horizontal sur les grands écrans. Enveloppez des widgets comme GridView ou ListView dans un ConstrainedBox ou Container et définissez un maxWidth dans BoxConstraints.
  • Rendu Paresseux : Utilisez toujours ListView.builder ou GridView.builder lors du rendu de listes avec un nombre d'éléments inconnu ou important.

Comportements des Appareils et de l'Orientation

Assurez-vous que l'application se comporte correctement sur tous les facteurs de forme d'appareil et méthodes d'entrée.

  • Ne verrouillez pas l'orientation de l'écran. Le verrouillage de l'orientation provoque des problèmes de mise en page graves sur les appareils pliables, aboutissant souvent à un lettrage (l'application centrée avec des bordures noires). Les niveaux de grand format Android nécessitent la prise en charge du portrait et du paysage.
  • Secours pour l'Orientation Verrouillée : Si les exigences métier exigent strictement une orientation verrouillée, utilisez l'API Display pour récupérer les dimensions physiques de l'écran au lieu de MediaQuery. MediaQuery ne reçoit pas la taille de fenêtre plus grande en modes de compatibilité.
  • Prendre en Charge Plusieurs Entrées : Implémentez la prise en charge des souris basiques, des pavés tactiles et des raccourcis clavier. Assurez-vous que les cibles tactiles sont dimensionnées de manière appropriée et que la navigation au clavier est accessible.

Flux de Travail : Construire une Mise en Page Adaptative

Suivez ce flux de travail pour implémenter une mise en page qui s'adapte aux BoxConstraints disponibles.

Progression de la Tâche :

  • [ ] Identifiez le widget cible qui nécessite un comportement adaptatif.
  • [ ] Enveloppez l'arborescence des widgets dans un LayoutBuilder.
  • [ ] Extrayez le constraints.maxWidth du rappel du constructeur.
  • [ ] Définissez un point de rupture adaptatif (par exemple, largeScreenMinWidth = 600).
  • [ ] Si maxWidth > largeScreenMinWidth : Retournez une mise en page d'écran large (par exemple, une Row plaçant une barre latérale de navigation et une zone de contenu côte à côte).
  • [ ] Si maxWidth <= largeScreenMinWidth : Retournez une mise en page d'écran petit (par exemple, une Column ou une approche de style de navigation standard).
  • [ ] Exécutez le validateur -> redimensionnez la fenêtre de l'application -> examinez les transitions de mise en page -> corrigez les erreurs de débordement.

Flux de Travail : Optimiser pour les Grand Écrans

Suivez ce flux de travail pour empêcher les éléments de l'interface utilisateur de s'étirer anormalement sur les grands écrans.

Progression de la Tâche :

  • [ ] Identifiez les composants pleine largeur (par exemple, ListView, blocs de texte, formulaires).
  • [ ] Si vous optimisez une liste : Convertissez ListView.builder en GridView.builder en utilisant SliverGridDelegateWithMaxCrossAxisExtent pour ajuster automatiquement le nombre de colonnes en fonction de la taille de la fenêtre.
  • [ ] Si vous optimisez un formulaire ou un bloc de texte : Enveloppez le composant dans un ConstrainedBox.
  • [ ] Appliquez BoxConstraints(maxWidth: [optimal_width]) au ConstrainedBox.
  • [ ] Enveloppez le ConstrainedBox dans un widget Center pour conserver le contenu contraint centré sur les grands écrans.
  • [ ] Exécutez le validateur -> testez sur la cible de bureau/tablette -> examinez l'étirement horizontal -> ajustez maxWidth ou les étendues de la grille.

Exemples

Mise en Page Adaptative en Utilisant LayoutBuilder

Démontre le passage d'une mise en page mobile à une mise en page de bureau en fonction de la largeur disponible.

import 'package:flutter/material.dart';

const double largeScreenMinWidth = 600.0;

class AdaptiveLayout extends StatelessWidget {
  const AdaptiveLayout({super.key});

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth > largeScreenMinWidth) {
          return _buildLargeScreenLayout();
        } else {
          return _buildSmallScreenLayout();
        }
      },
    );
  }

  Widget _buildLargeScreenLayout() {
    return Row(
      children: [
        const SizedBox(width: 250, child: Placeholder(color: Colors.blue)),
        const VerticalDivider(width: 1),
        Expanded(child: const Placeholder(color: Colors.green)),
      ],
    );
  }

  Widget _buildSmallScreenLayout() {
    return const Placeholder(color: Colors.green);
  }
}

Contraindre la Largeur sur les Grand Écrans

Démontre la prévention d'un widget de consommer tout l'espace horizontal.

import 'package:flutter/material.dart';

class ConstrainedContent extends StatelessWidget {
  const ConstrainedContent({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ConstrainedBox(
          constraints: const BoxConstraints(
            maxWidth: 800.0, // Largeur maximale pour la lisibilité
          ),
          child: ListView.builder(
            itemCount: 50,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text('Item $index'),
              );
            },
          ),
        ),
      ),
    );
  }
}