LoginSignup
4
9

More than 3 years have passed since last update.

自分用メモ flutterのPageViewをほかのイベントからページ切り替えする方法

Last updated at Posted at 2020-02-25

PageViewをプログラム側からページ切り替えしようと思ったら詰まった

やりたかったこと

ボタンとドロップダウンリストを使ってページ切り替え

説明に「PageControllerのinitialPage:で最初に表示するページを設定する」みたいなことが書いてあったので、なるほどPageControllerを再作成して切り替えたいページを指定するんだなと思って↓を書いた


//MyPageWidgetは省略

class MyPageState extends State<MyPageWidget>{
   var _currentPage = 0;
   @Override 
   Widget build(BuildContext context) {
      final controller = PageController(initialPage: _currentPage);
      return Column(
      children: <Widget>[
        Row( //ボタン用の行widget
          children: <Widget>[
            IconButton( //前ページボタン
              icon: Icon(Icons.navigate_before),
              onPressed: _currentPage > 0 ? () { //クリックイベント処理
                setState(){ _currentPage--;};
              } : null,
            ),
            Expanded( //ドロップダウンリストを余白いっぱいに引き伸ばす
              child: DropdownButton( //ドロップダウンリスト
                isExpanded: true,
                value: _current,
                items: List.generate(
                    12,
                    (index) => DropdownMenuItem(
                          value: index,
                          child: Text(
                            index.toString(),
                            textAlign: TextAlign.center,
                            textScaleFactor: 1.5,
                          ),
                        )),
                onChanged: (value) { //アイテム選択イベント処理
                  if (value is int) setState(){ _currentPage = value; };
                },
              ),
            ),
            IconButton( //次ページボタン
              icon: Icon(Icons.navigate_next),
              onPressed: _current < 11 ? (){ setState(){ _currentPage++ ;} : null,
            )
          ],
        ),
        Expanded( //PageViewはサイズが可変なので、Column Widgetに入れるときはこれに入れる
          child: PageView.builder(
              itemCount: 12,
              controller: _mController,
              onPageChanged: (index){ //ページ変更イベント処理
                setState(() {
                  _current = index;
                });
              },
              itemBuilder: (context, index){
                 return Center( child: Text((index + 1).toString() + "ページ",textScaleFactor: 3;
              }),
        )
      ],
    )

※動きません

flutterのPageViewリファレンスページをよく見ると

The PageController can also be used to control the PageController.initialPage, which determines which page is shown when the PageView is first constructed,

ページビューが最初に作成された時に表示されるページを決定する(雑訳)

つまりこれ、最初の一回だけページを指定するのであって、ページを移動するためには使えない、ということか!?

PageControllerのリファレンスを見ると……

METHODS

animateToPage
attach
createScrollPosition
jumpToPage
nextPage
previousPage
addListener

↑はい、この辺を使うんですね分かります。


//MyPageWidgetは省略

class MyPageState extends State<MyPageWidget>{
   var _currentPage = 0;
   var duration = Duration(milisecond: 200); //アニメーションする時間
   var curve = Curves.fastInSlowOut; //アニメーションの動き
   @Override 
   Widget build(BuildContext context) {
      final controller = PageController();

      //色々省略

      onPressed: _current > 0 ? (){ //前ページボタンイベント処理
           controller.previousPage(duration: duration,curve: curve);
         },
      //色々省略
                onChanged: (value) { //ドロップダウンリストアイテム選択イベント処理
                  if (value is int) {
                     controller.jumpToPage(value);
                  };
                },
       //色々省略
       onPressed: _current > 0 ? (){ //前ページボタンイベント処理
           controller.nextPage(duration: duration,curve: curve);
         },
   //色々省略
}

*これで動いた
*durationやcurveを変えるとアニメーションも変わる

気付かなかった理由

flutterのUIフレームワークになれすぎた。
何かを変更するときは値を変えてsetState()すれば終わりだと思ってた。
っていうかAnimatedContainerはsetState()で値変えたら自動でアニメーションするからさあ……(見苦しい言い訳)

androidStudioではずっとそうやって使ってきたのに完全に忘れちゃってたな。

おまけ

これらのメソッドはFutureクラスを返すので、


   controller.nextPage( duration: duration, curve:curve)
      .whenComplete((){
          //なにかの処理
       });

こうすれば、ページ切り替えが終わったあとに何らかの処理をする事ができる。

4
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
9