Desvanecimiento de una pagina con FadeForwardsPage


Avatar de Pedro Cortez

¿Quieres agregar un desvanecimiento de transición para tus páginas? En esta guía, te explico cómo utilizar fadeforwardspagetransitionsbuilder para añadir una animación cuando cambias de página.


FadeForwardsPageTransitionsBuilder

Cambiar de página con un desvanecimiento hacia adelante (FadeForwardsPageTransitionsBuilder)

El FadeForwardsPageTransitionsBuilder es una animación de transición de Flutter que imita la animación de transición de páginas en Android U. Hace que una página se deslice de derecha a izquierda mientras se desvanece, y luego realiza la animación inversa cuando se regresa hacia atrás.

Aquí tienes un ejemplo sencillo para implementar esta animación en una aplicación Flutter, que puedes adaptar según tus necesidades:

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('Discusiones', 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('Persona $index');
                    final CircleAvatar avatar = CircleAvatar(
                      backgroundColor: Colors.primaries[index],
                    );
                    final String message =
                        index.isEven
                            ? '¡Hola! Me llamo Persona $index'
                            : "¿Cómo estás? Soy Persona $index";
                    return ListTile(
                      leading: avatar,
                      title: contactName,
                      subtitle: Text(message),
                      trailing: Text('$index minutos atrás'),
                      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),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Modificar la transición según tus necesidades

El widget FadeForwardsPageTransitionsBuilder ofrece varias propiedades que puedes modificar para personalizar la animación de transición. Estas propiedades incluyen el color de fondo y la duración de la animación. A continuación, se muestra cómo puedes ajustarlas.

Propiedad backgroundColor

Esta propiedad te permite definir el color de fondo que se muestra durante la transición entre dos páginas. Por ejemplo:

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

Propiedad transitionDuration

transitionDuration permite gestionar la duración de la transición hacia la nueva página.

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

Por el contrario, la propiedad reverseTransitionDuration permite controlar la duración de la transición cuando se regresa hacia atrás:

FadeForwardsPageTransitionsBuilder(
  reverseTransitionDuration: Duration(milliseconds: 400),
)

Avatar de Pedro Cortez