Changer de page avec un fondu avec FadeForwardsPage


Avatar de Pierre Courtois

Vous souhaitez ajouter un fondu de transition pour vos pages ? Dans ce guide, je vous explique comment utiliser fadeforwardspagetransitionsbuilder pour ajouter une animation quand vous changez de page.


FadeForwardsPageTransitionsBuilder

Changer de page avec un fondu avant (FadeForwardsPageTransitionsBuilder)

La FadeForwardsPageTransitionsBuilder est une animation de transition de Flutter qui imite l’animation de transition des pages sur Android U. Elle fait en sorte qu’une page glisse de la droite vers la gauche tout en s’estompant, puis fasse l’animation inverse quand on revient en arrière.

Voici un exemple simple pour implémenter cette animation dans une application Flutter et que vous pouvez adapter selon vos besoins :

import 'package:flutter/material.dart';

void main() => runApp(const TransitionApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        pageTransitionsTheme: PageTransitionsTheme(
          builders: Map<TargetPlatform, PageTransitionsBuilder>.fromIterable(
            TargetPlatform.values,
            value: (_) => const FadeForwardsPageTransitionsBuilder(),
          ),
        ),
      ),
      home: const ConversationList(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(icon: const Icon(Icons.menu), onPressed: () {}),
        actions: <Widget>[
          IconButton(icon: const Icon(Icons.search), onPressed: () {}),
          IconButton(icon: const Icon(Icons.settings), onPressed: () {}),
        ],
      ),
      body: Column(
        children: <Widget>[
          Text('Discussions', style: Theme.of(context).textTheme.headlineLarge),
          Expanded(
            child: Padding(
              padding: const EdgeInsets.all(20.0),
              child: Card(
                clipBehavior: Clip.antiAlias,
                elevation: 0,
                color: Theme.of(context).colorScheme.surfaceContainerLowest,
                child: ListView(
                  children: List<Widget>.generate(Colors.primaries.length, (int index) {
                    final Text contactName = Text('Personne $index');
                    final CircleAvatar avatar = CircleAvatar(
                      backgroundColor: Colors.primaries[index],
                    );
                    final String message =
                        index.isEven
                            ? 'Salut ! Je m\'appelle Personne $index'
                            : "Comment ça va ? C'est Personne $index";
                    return ListTile(
                      leading: avatar,
                      title: contactName,
                      subtitle: Text(message),
                      trailing: Text('$index minutes ago'),
                      onTap: () {
                        Navigator.of(context).push(
                          MaterialPageRoute<DiscussionPage>(
                            builder:
                                (BuildContext context) => DiscussionPage(
                                  contactName: contactName,
                                  avatar: avatar,
                                  message: message,
                                ),
                          ),
                        );
                      },
                    );
                  }),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class DiscussionPage extends StatelessWidget {
  const DiscussionPage({
    super.key,
    required this.contactName,
    required this.avatar,
    required this.message,
  });
  final Text contactName;
  final CircleAvatar avatar;
  final String message;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: const BackButton(),
        title: contactName,
        centerTitle: false,
        actions: <Widget>[
          IconButton(icon: const Icon(Icons.search), onPressed: () {}),
          IconButton(icon: const Icon(Icons.settings), onPressed: () {}),
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: IntrinsicHeight(
          child: Row(
            children: <Widget>[
              avatar,
              ConstrainedBox(
                constraints: const BoxConstraints(minHeight: 50),
                child: Card(
                  elevation: 0.0,
                  shape: const RoundedRectangleBorder(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(20),
                      topRight: Radius.circular(20),
                      bottomLeft: Radius.circular(5),
                      bottomRight: Radius.circular(20),
                    ),
                  ),
                  color: Theme.of(context).colorScheme.surfaceContainerLowest,
                  child: Center(
                    child: Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 15.0),
                      child: Text(message),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Modifier la transition selon vos besoins

Le widget FadeForwardsPageTransitionsBuilder propose plusieurs propriétés que vous pouvez modifier pour personnaliser l’animation de transition. Ces propriétés incluent la couleur de fond et la durée de l’animation. Voici comment vous pouvez les ajuster.

Propriété backgroundColor

Cette propriété vous permet de définir la couleur de fond qui s’affiche pendant la transition entre deux pages. Par exemple :

FadeForwardsPageTransitionsBuilder(
  backgroundColor: Colors.red.withValues(alpha: 0.5),
)

Propriété transitionDuration

transitionDuration permet de gérer la durée de la transition vers la nouvelle page.

FadeForwardsPageTransitionsBuilder(
  transitionDuration: Duration(milliseconds: 600),
)

à l’inverse la propriété reverseTransitionDuration permet de controller la durée de la transition quand on retourne en arrière :

FadeForwardsPageTransitionsBuilder(
  reverseTransitionDuration: Duration(milliseconds: 400),
)
Avatar de Pierre Courtois