LoginSignup
1
1

More than 3 years have passed since last update.

FlutterのPageView(スワイプとボタンでスクロール)

Last updated at Posted at 2020-12-08

はじめに

業務でPageViewを使ったので、備忘録代わりにまとめてみます。
Flutter初心者なので、間違ってる部分があったらご指摘ください。

参考

下記を参考にさせていただきました。
https://qiita.com/yoshua/items/741038cb8c8c8bf0e873

動作イメージ

pageView.gif

PageViewのスワイプと、ボタンタップでスクロールするようにしました。

実装

ここは特にコメントはありません。

class TestScreen extends StatefulWidget {
  /// constructors
  const TestScreen({
    Key key,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => _TestScreenState();
}

initState時にPageControllerを用意します。
addListenerでスクロールの検知ができます。
あとで出てくる_MyPageView部分が、今回メインで作成したいPageViewです。
そのほか、RaisedButtonのonPressedでページ送り/戻しをしています。
todoで書いてありますが、_currentPageのmaxとminの制御が必要です
(動的に変化する場合も多いと思うので、ここでは割愛してます)。

class _TestScreenState extends State<TestScreen> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  final _myPageViewKey = GlobalKey<_MyPageViewState>();

  PageController _pageController;
  int _currentPage = 0;

  @override
  void initState() {
    super.initState();

    _pageController = PageController();
    _pageController.addListener(() {
      final nextPage = _pageController.page.round();
      if (_currentPage != nextPage) {
        _currentPage = nextPage;
      }
    });
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: const Text('test'),
      ),
      backgroundColor: Colors.white,
      body: Builder(
        builder: (context) => SafeArea(
          child: Column(
            children: [
              _MyPageView(
                key: _myPageViewKey,
                pageController: _pageController,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  RaisedButton(
                    onPressed: () {
                      _currentPage--;  // todo: ページ数に応じた制御が必要
                      _pageController.animateToPage(_currentPage,
                          duration: const Duration(milliseconds: 300),
                          curve: Curves.easeInOut);
                    },
                    child: const Text('前へ'),
                  ),
                  RaisedButton(
                    onPressed: () {
                      _currentPage++;   // todo: ページ数に応じた制御が必要
                      _pageController.animateToPage(_currentPage,
                          duration: const Duration(milliseconds: 300),
                          curve: Curves.easeInOut);
                    },
                    child: const Text('次へ'),
                  ),
                ],
              ),
            ],
          ),
        ),
      ));
}

今回メインで作成したいPageViewです。

class _MyPageView extends StatefulWidget {
  /// constructors
  const _MyPageView({
    Key key,
    this.pageController,
  }) : super(key: key);

  final PageController pageController;

  @override
  State<StatefulWidget> createState() => _MyPageViewState();
}

PageView自体と、各ページを作成します。

class _MyPageViewState extends State<_MyPageView> {
  var _currentViewPage = 0;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) => Column(
        children: [
          _buildPageView(),
        ],
      );

  Widget _buildPageView() => ConstrainedBox(
        constraints: const BoxConstraints.expand(height: 100),
        child: PageView(
          onPageChanged: (page) {
            _currentViewPage = page;
          },
          controller: widget.pageController,
          children: List<Widget>.generate(
              10,   // ページ数 todo: 動的に変えるか、定数にする
              _buildPageViewChild),
        ),
      );

  // ページビュー各ページ
  Widget _buildPageViewChild(int pageIndex) => Row(
        children: [
          Expanded(
            child: Container(
              color: Colors.grey,
              child: Center(child: Text('$pageIndex')),
            ),
          )
        ],
      );
}
1
1
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
1
1