Flutter PageView Examples – Custom Animation in PageView.builder

PageView can be used to show a scrollable list that works page by page. Each child of a page view is forced to be the same size as the viewport.

Basics

Display a list of 3 pages with scroll direction as Axis.horizontal.

import 'package:flutter/material.dart';

class PageViewPage extends StatefulWidget {
  @override
  _PageViewPageState createState() => _PageViewPageState();
}

class _PageViewPageState extends State<PageViewPage> {

  final PageController _controller = PageController(initialPage: 0);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('PageView'),),
      body: SafeArea(
        child: PageView(
          controller: _controller,
          children: [
            Container(
              color: Colors.red,
              child: Center(
                  child: Text(
                    'Page 1',
                    style: TextStyle(fontSize: 18.0),
                  )),
            ),
            Container(
              color: Colors.green,
              child: Center(
                  child: Text(
                    'Page 2',
                    style: TextStyle(fontSize: 18.0),
                  )),
            ),
            Container(
              color: Colors.blue,
              child: Center(
                  child: Text(
                    'Page 3',
                    style: TextStyle(fontSize: 18.0),
                  )),
            )
          ],

        ),
      ),
    );
  }
}

PageView.builder and custom animation

We use PageView.builder constructor to build children wrapped in their respective animation widget for custom page transition.

The _currentPage variable is a double value. It indicates the progress of switching pages.

import 'package:flutter/material.dart';

class PageViewPage extends StatefulWidget {
  @override
  _PageViewPageState createState() => _PageViewPageState();
}

class _PageViewPageState extends State<PageViewPage> {

  List<Widget> _pages = [];
  final PageController _controller = PageController(initialPage: 0);
  double? _currentPage = 0;
  

  @override
  void initState() {
    _pages = [
      Container(
        color: Colors.red,
        child: Center(
            child: Text(
              'Page 1',
              style: TextStyle(fontSize: 18.0, color: Colors.white),
            )),
      ),
      Container(
        color: Colors.green,
        child: Center(
            child: Text(
              'Page 2',
              style: TextStyle(fontSize: 18.0, color: Colors.white),
            )),
      ),
      Container(
        color: Colors.blue,
        child: Center(
            child: Text(
              'Page 3',
              style: TextStyle(fontSize: 18.0, color: Colors.white),
            )),
      )
    ];

    //add
    _controller.addListener(() {
      setState(() {
        _currentPage = _controller.page;
      });
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(title: Text('PageView')),
      body: SafeArea(
        child: PageView.builder(
          itemBuilder: (context, index) {
            return Transform(
              transform: Matrix4.identity()..rotateZ(_currentPage! - index),
              child: _pages[index],
            );
          },
          scrollDirection: Axis.horizontal,
          controller: _controller,
          itemCount: _pages.length,
        ),
      ),
    );
  }
}

Leave a Comment

Your email address will not be published. Required fields are marked *