🌊

【Flutter】PageViewで一定時間経過ごとにページを切り替える

2023/01/12に公開

はじめに

この記事では、PageViewを使用して、一定時間(○秒)が経過するごとにページを切り替える処理の作り方を記載します。

本記事で使用しているFlutterバージョン: 3.3.10


ベースとなるコードを作成する

まずはベースとなる、PageViewを使ったサンプルを作成します。

このサンプルでは、MyPageViewWidgetクラスがPageViewを使用して、各ページに画像を表示しています。

import 'package:flutter/material.dart';

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

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

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'PageView Sample',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text("PageView Sample"),
        ),
        body: const MyPageViewWidget(),
      ),
    );
  }
}

class MyPageViewWidget extends StatefulWidget {
  const MyPageViewWidget({Key? key}) : super(key: key);

  
  State<MyPageViewWidget> createState() => _MyPageViewWidgetState();
}

class _MyPageViewWidgetState extends State<MyPageViewWidget> {
  
  Widget build(BuildContext context) {
    final height = MediaQuery.of(context).size.height;
    final width = MediaQuery.of(context).size.width;

    return SizedBox(
      height: height * 0.5,
      width: width,
      child: PageView(
        children: [
          Container(
            decoration: const BoxDecoration(
              image: DecorationImage(
                fit: BoxFit.cover,
                image: NetworkImage("https://picsum.photos/id/237/300/200"),
              ),
            ),
          ),
          Container(
            decoration: const BoxDecoration(
              image: DecorationImage(
                fit: BoxFit.cover,
                image: NetworkImage("https://picsum.photos/id/20/300/200"),
              ),
            ),
          ),
          Container(
            decoration: const BoxDecoration(
              image: DecorationImage(
                fit: BoxFit.cover,
                image: NetworkImage("https://picsum.photos/id/24/300/200"),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

このコードを実行すると、つぎのようになります。この添付動画は手動でページを切り替えています。

PageView 初期動作


一定時間経過ごとにページを切り替える

ベースとなるコードが用意できたので、つぎは一定時間経過ごとにページを切り替えるコードを書いていきます。

一定時間経過でPageViewのページを切り替える処理は、PageControllerTimer.periodicを使います。

まずは、_MyPageViewWidgetStateに処理を追加します。

import 'dart:async'; // ① ファイルの一番上に追加

class _MyPageViewWidgetState extends State<MyPageViewWidget> {
+  final _pageController = PageController(initialPage: 0); // ②
+  int _currentPage = 0; // ③

+  
+  void initState() { // ④
+    super.initState();
+
+    Timer.periodic(const Duration(seconds: 2), (Timer timer) {
+      if (_currentPage < 2) { // ⑤
+        _pageController.nextPage(
+          duration: const Duration(milliseconds: 500),
+          curve: Curves.ease,
+        );
+      } else {
+        _pageController.jumpToPage(0); // ⑥
+      }
+    });
+  }
...

Timer.periodicを使用するため、①のインポートをファイルの一番上に追加します。
続いて、PageControllerと現在ページを扱うメンバー変数を用意します(②と③)。
initStateでTimer.periodicを呼び出し、2秒経過するごとに実行したい処理を記述します。
このサンプルでは用意しているページが3つであるため、3ページ目(インデックスが2)が表示されている場合(⑤)は、最初のページに遷移するように設定します(⑥)。

続いて、PageViewの生成処理をつぎのように変更します。

...
    return SizedBox(
      height: height * 0.5,
      width: width,
+      child: PageView(
+        controller: _pageController, // ①
+        onPageChanged: ((int index) { // ②
+          setState(() {
+            _currentPage = index;
+          });
+        }),
        children: [
          Container(
...

PageControllerを使ってPageViewを制御できるようにするために、_pageControllerを引数に追加します(①)。
そして、PageViewのページが切り替わったときに、setStateを用いて_currentPageを書き換えるために、onPageChangedを設定しています。

以上のように変更すると、一定時間でページが切り替わるようになります。

PageView 一定時間でページ切り替え

本記事と同様のサンプルコードをGitHubに置いていますので、参考にしてください。
https://github.com/aiiro/flutter-implementation-samples/tree/main/page_view

Discussion