PageView in Flutter | Everything about PageView in Flutter

PageView in Flutter | Everything about PageView in Flutter

PageView is one of the best widgets in Flutter. You can make your screen is swipeable and in this tutorial, we are going to learn PageView.

Project Setup

We don't need any package to install for this tutorial. Also this tutorial we are going to use Containers in our PageView for simplicity.

Create a new Flutter project and come to the body field of the Scaffold widget. Make sure to delete the rest of the sample code provided. Also, remove the FloatingActionButton widget. We do not need it for our tutorial. Inside the body field of Scaffold, use the PageView widget and declare the children field here.

The code should be like below. If cannot delete the code properly copy and paste the code below in the main.dart file.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'PageView Tutorial',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'PageView Tutorial'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: PageView(
        children: [],
      ),
    );
  }
}

Code

Now in the children field, we will add three Container of different colours with some text. The Container widget should look like below.

Container(
  decoration: BoxDecoration(
    color: Colors.red,
  ),
  child: Center(
    child: Text(
      'Red',
      style: TextStyle(
        color: Colors.white,
        fontSize: 32.0,
      ),
    ),
  ),
),

As I made for Red, you can make as many Container widgets as you want. I have made Yellow and Green colours.

Now run your app. The app should look like below.

We got a nice animation out of the box from the PageView animation.

Now is the time to learn about PageController.

PageView widgets can be controlled with the help of a controller made for this widget and that is PageController. Let us discuss some fields used by PageController.

When initializing we get three controls of PageView from the controller.

  1. initialPage : This specifies at first which child index to show. By default, it is 0. In our app Red Container has an index of 0, Yellow has the index of 1 and Green has the index of 2. So if we specify in our app as initialPage 2 then at first we will see green. Note that the app will function the same as above with all widgets at the same position, rather we will see Green Container after running the app.

  2. keepPage: It takes a boolean type of value and is by default true. It specifies if your PageView is destroyed and recreated the controller will remember the last page you swiped to. If set to false, when the PageView is recreated and the controller is the same the page will set to the initialPage.

  3. It takes a double value and the default is 1.0. The range is 0-1. As the field says, you have to input the amount of screen each page should occupy. Value 1 means a full screen, value half or 0.5 means half the width of the screen.

Design

Now let us add one more functionality to our app. We will add two buttons to our Containers, one next and the other previous. On clicking the button we will swipe through screens without actually swiping. But before that, we need to initialize our PageController and add it to our PageView.

Initialize the controller.

PageController _pageController = PageController();

Next inside the PageView, add the controller.

controller: _pageController,

Let us separate the Container widget to make our code simple. I am creating a new method that will return the Container widget. We will pass the colour and name of the colour to the method.

Widget colouredContainer(Color color, String colorName) {
  return Container(
    decoration: BoxDecoration(
      color: color,
    ),
    child: Center(
      child: Text(
        colorName,
        style: TextStyle(
          color: Colors.white,
          fontSize: 32.0,
        ),
      ),
    ),
  );

Replace the Containers in the PageView with the colouredContainer widget that we made just now. Make Sure that the method colouredContainer is inside the State class.

colouredContainer(Colors.red, 'Red'),
colouredContainer(Colors.yellow, 'Yellow'),
colouredContainer(Colors.green, 'Green'),

Now let us modify the Container's child widget. Replace the Text widget with Column Widget with the same Text Widget and two ElevatedButton widgets. The two widgets are, one is Next and another is Previous.

Column(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Text(
      colorName,
      style: TextStyle(
        color: Colors.white,
        fontSize: 32.0,
      ),
    ),
    ElevatedButton(
      onPressed: () {},
      child: Text('Next'),
    ),
    ElevatedButton(
      onPressed: () {},
      child: Text('Previous'),
    )
  ],
),

In the onPressed() function we will write the code for screen change.

if(_pageController.hasClients)
{
  _pageController.nextPage(duration: duration, curve: curve)
}

So the _pageController.hasClients return boolean type value and we need to ensure that when we are using the controller there should not be any runtime errors of saying controller not attached to the widget.

Next we are using _pageController.nextPage function. It means to navigate to the next page. It takes two values, first duration which takes Duration type value and we want 1 second and next curve which takes Curve type of value. We will use easeIn Curve.

_pageController.nextPage(
  duration: Duration(seconds: 1),
  curve: Curves.easeIn,
);

Similarly in the Previous button, we will use previousPage which also takes similar values.

_pageController.previousPage(
  duration: Duration(seconds: 1),
  curve: Curves.easeIn,
);

Run the app.

Extra Features

PageController not only has these two features but also jumpTo, animateTo, notifyListeners etc.

You can follow the official documentation for more features here.

Result

The whole code is here below.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'PageView Tutorial',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'PageView Tutorial'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  PageController _pageController = PageController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: PageView(
        controller: _pageController,
        children: [
          colouredContainer(Colors.red, 'Red'),
          colouredContainer(Colors.yellow, 'Yellow'),
          colouredContainer(Colors.green, 'Green'),
        ],
      ),
    );
  }

  Widget colouredContainer(Color color, String colorName) {
    return Container(
      decoration: BoxDecoration(
        color: color,
      ),
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Text(
              colorName,
              style: TextStyle(
                color: Colors.white,
                fontSize: 32.0,
              ),
            ),
            ElevatedButton(
              onPressed: () {
                if (_pageController.hasClients) {
                  _pageController.nextPage(
                    duration: Duration(seconds: 1),
                    curve: Curves.easeIn,
                  );
                }
              },
              child: Text('Next'),
            ),
            ElevatedButton(
              onPressed: () {
                if (_pageController.hasClients) {
                  _pageController.previousPage(
                    duration: Duration(seconds: 1),
                    curve: Curves.easeIn,
                  );
                }
              },
              child: Text('Previous'),
            )
          ],
        ),
      ),
    );
  }
}

In this tutorial, we learned the new widget PageView. Hope this tutorial helped you. If you have any problems regarding this tutorial or other issues comment below and let me know.

Thank You.

Did you find this article valuable?

Support All About Flutter | Flutter and Dart by becoming a sponsor. Any amount is appreciated!