Bases de l'interface utilisateur Flutter
Création d’interfaces graphiques
Section titled “Création d’interfaces graphiques”Flutter utilise un système de widgets composables pour créer des interfaces utilisateur. Chaque élément de l’interface est un widget, des éléments simples comme le texte aux structures complexes comme les écrans complets.
Scaffold : Structure d’un écran
Section titled “Scaffold : Structure d’un écran”Le Scaffold fournit la structure de base d’un écran dans une application Material Design. Il offre des emplacements prédéfinis pour les éléments courants de l’interface utilisateur.
AppBar
Section titled “AppBar”L’AppBar permet d’afficher :
- le titre de l’application
- à gauche : généralement un bouton retour
- une liste de boutons d’actions
import 'package:flutter/material.dart';
void main() => runApp( MaterialApp( home: Scaffold( appBar: AppBar( leading: IconButton( icon: Icon(Icons.arrow_left), onPressed: () {}, ), title: const Text('Home'), actions: [ IconButton( icon: Icon(Icons.info), onPressed: () => print('Infos'), ), ], ), ), debugShowCheckedModeBanner: false, ),);Drawer et EndDrawer
Section titled “Drawer et EndDrawer”Les scaffold permettent d’afficher un drawer : un panneau latéral modal (drawer et endDrawer).
Lorsqu’un Drawer est présent, l’AppBar intègre par défaut un bouton “burger”.
Scaffold( appBar: AppBar( title: const Text('Drawer Demo'), ), drawer: Drawer( child: ListView( padding: EdgeInsets.zero, children: const <Widget>[ DrawerHeader( decoration: BoxDecoration( color: Colors.blue, ), child: Text( 'Drawer Header', style: TextStyle( color: Colors.white, fontSize: 24, ), ), ), ListTile( leading: Icon(Icons.message), title: Text('Messages'), ), ListTile( leading: Icon(Icons.account_circle), title: Text('Profile'), ), ListTile( leading: Icon(Icons.settings), title: Text('Settings'), ), ], ), ),)FloatingActionButton
Section titled “FloatingActionButton”Le scaffold intègre un emplacement pour un FloatingActionButton (FAB). Ce bouton est positionné en bas à droite ou en bas au milieu, “au-dessus” du contenu du body.
import 'package:flutter/material.dart';
void main() { runApp(const MaterialApp(home: MainScreen()));}
class MainScreen extends StatefulWidget { const MainScreen({Key? key}) : super(key: key);
@override State<MainScreen> createState() => _MainScreenState();}
class _MainScreenState extends State<MainScreen> { int value = 0;
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), floatingActionButton: FloatingActionButton( onPressed: () => print('ADD'), child: const Icon(Icons.add), ), ); }}L’AppBar permet également l’affichage d’une barre d’onglets scrollable/swipable.
import 'package:flutter/material.dart';
void main() { runApp(const MaterialApp(home: MainScreen()));}
class MainScreen extends StatefulWidget { const MainScreen({Key? key}) : super(key: key);
@override _MainScreenState createState() => _MainScreenState();}
class _MainScreenState extends State<MainScreen> with SingleTickerProviderStateMixin { final tabs = const [ Tab(text: 'Livres'), Tab(text: 'Films'), Tab(text: 'Disques'), ];
late TabController tabController;
@override void initState() { tabController = TabController( length: tabs.length, initialIndex: 0, vsync: this, ); super.initState(); }
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( bottom: TabBar( controller: tabController, tabs: tabs, isScrollable: true, ), ), body: TabBarView( controller: tabController, children: const <Widget>[ Center(child: Text('Livres')), Center(child: Text('Films')), Center(child: Text('Musique')), ], ), ); }}BottomNavigationBar
Section titled “BottomNavigationBar”Le BottomNavigationBar permet de créer une navigation par onglets en bas de l’écran.
import 'package:flutter/material.dart';
void main() { runApp(MaterialApp( home: MainScreen(icons), ));}
List<Icon> icons = const [ Icon(Icons.music_note), Icon(Icons.book),];
class MainScreen extends StatefulWidget { final List<Icon> icons; const MainScreen(this.icons, {Key? key}) : super(key: key);
@override _MainScreenState createState() => _MainScreenState();}
class _MainScreenState extends State<MainScreen> { int pageIndex = 0; late List<Widget> subviews;
@override void initState() { subviews = widget.icons; super.initState(); }
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.shifting, items: const [ BottomNavigationBarItem( icon: Icon(Icons.music_note), label: 'Music', ), BottomNavigationBarItem( icon: Icon(Icons.book), label: 'Livre', ), ], currentIndex: pageIndex, fixedColor: Colors.cyan, unselectedItemColor: Colors.grey.shade500, onTap: (index) => setState(() => pageIndex = index), ), body: Center(child: subviews[pageIndex]), ); }}Text and Images
Section titled “Text and Images”Le widget Text permet d’afficher du texte avec différentes options de style.
const Text( 'Hello Flutter', style: TextStyle(color: Colors.blue), textAlign: TextAlign.start, maxLines: 3, overflow: TextOverflow.ellipsis,)Rich Text
Section titled “Rich Text”Pour créer du texte avec différents styles dans le même widget :
const Text.rich( TextSpan( text: 'Hello', children: [ TextSpan( text: 'Flutter', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 32, color: Colors.white, backgroundColor: Colors.cyan, ), ), ], ), style: TextStyle(color: Colors.blue), textAlign: TextAlign.start, maxLines: 3, overflow: TextOverflow.ellipsis,)Images
Section titled “Images”Le widget Image dispose de 4 constructeurs :
Image.networkImage.assetImage.fileImage.memory
Il permet de définir :
- une taille
- un coefficient d’échelle
- une teinte
- l’opacité
- etc…
Image.asset
Section titled “Image.asset”Pour embarquer des assets (images, polices, textes), on les déclare dans le fichier pubspec.yaml :
flutter: uses-material-design: true assets: - assets/logo.png - assets/config.json - packages/my_assets/assets/image.pngPour utiliser cet asset :
Image.asset('assets/dart.png'),final config = await rootBundle.loadString('assets/config.json');Material helpers
Section titled “Material helpers”Flutter fournit une large collection d’icônes Material Design :
Icon(Icons.music_note)Consultez material.io/icons pour voir toutes les icônes disponibles.
Colors
Section titled “Colors”Material Design propose une palette de MaterialColors. Chacune de ces couleurs contient plusieurs nuances.
Colors.cyanColors.cyan.shade100Colors.cyan.shade500Colors.cyan.shade900Colors.cyanAccentColors.cyanAccent.shade100Container and Card
Section titled “Container and Card”Container
Section titled “Container”Ce widget a la particularité d’aller à l’encontre du principe de composition. En effet, ce widget intègre la logique de plusieurs autres widgets et permet de déclarer :
- un padding
- une marge
- un alignment
- une taille : la largeur
widthet la hauteurheight - une couleur
color - une decoration de type
BoxDecoration, pouvant définir :- un borderRadius
- un contour
- une contrainte
constraints
Container( width: 300, height: 300, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.red, width: 3), boxShadow: const [ BoxShadow(blurRadius: 8, spreadRadius: 2) ], gradient: LinearGradient( colors: [Colors.cyan, Colors.blueGrey] ), ), alignment: Alignment.center, child: Text( 'Hello, World!', style: Theme.of(context).textTheme.headline4, ),);Card est un container Material ombré et légèrement arrondi :
Card( elevation: 5, color: Colors.grey.shade300, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Padding( padding: const EdgeInsets.all(8.0), child: Text('Settings : $category'), ), ElevatedButton( onPressed: context.pop, child: const Text('Fermer'), ) ], ), ),)Basic composition widgets
Section titled “Basic composition widgets”Padding
Section titled “Padding”Le widget Padding permet d’ajouter des espaces autour d’un widget enfant, exprimé à l’aide de EdgeInsets :
Column( crossAxisAlignment: CrossAxisAlignment.center, children: const [ Padding( padding: EdgeInsets.all(8.0), child: Icon(Icons.add), ), Text('Ajouter'), ],)Center
Section titled “Center”Le widget Center centre son enfant dans l’espace disponible :
Center( child: Text('Contenu centré'),)SizedBox
Section titled “SizedBox”Le widget SizedBox permet de contraindre la taille de son enfant ou de créer un espace vide :
// Contraindre la tailleSizedBox( width: 200, height: 100, child: Container(color: Colors.blue),)
// Créer un espace videSizedBox(height: 20) // Espace vertical de 20 pixelsCes widgets de composition de base sont essentiels pour créer des mises en page précises et bien structurées dans Flutter.