【Flutter】PageViewで一定時間経過ごとにページを切り替える
はじめに
この記事では、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のページを切り替える処理は、PageController
とTimer.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を設定しています。
以上のように変更すると、一定時間でページが切り替わるようになります。
本記事と同様のサンプルコードをGitHubに置いていますので、参考にしてください。
Discussion