42.【AppleMusicクローン】FlutterのPageViewを使って横スクロールのPageScrollを実現する
キーワードは PageView です。 今回は AppleMusicクローン の最初のセクションを実装していきます。
最終的に出来上がるデザインはこちらになります。
FlutterによるPageViewによるページ単位での横スクロール pic.twitter.com/tL8iabDTTS
— Tamappe@オンライン英会話のエンジニア (@tamapppe) April 3, 2020
最初は ListView の Axis.horizontal
を使って再現させようとしましたが挫折しました。
どうしても Item の index 単位での横スクロールができなかったので諦めようかと思いましたが
これを実現できるウィジェットが見つかりました。
PageView について
それでは PageView の使い方について紹介します。
PageView.builder( itemCount: [横に並べるウィジェットの個数(int)], controller: [PageControllerのインスタンス], itemBuilder: (BuildContext context, int itemIndex) { return [一つ当たりのwidget]; }, )
このように書くことで [一つ辺りのwidget] で設定したウィジェットを itemCount 分生成して ListView に並べることができます。
ソースコード
それでは、PageView を利用して最初のセクションを作成します。 最終的に出来上がるソースコードは次のようになります。
content_sliver_list.dart
import 'package:flutter/material.dart'; class ContentSliverList extends StatelessWidget { @override Widget build(BuildContext context) { return SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { if (index % 2 == 0) { return Padding( padding: const EdgeInsets.fromLTRB(20, 0, 20, 0), child: Divider( color: Colors.black, ), ); } else { return _buildHorizontalPageView(context, 4); } }, childCount: 20, ), ); } Widget _buildHorizontalPageView(BuildContext context, int itemCount) { return Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ SizedBox( // you may want to use an aspect ratio here for tablet support height: 300.0, child: PageView.builder( itemCount: itemCount, controller: PageController(viewportFraction: 0.9), itemBuilder: (BuildContext context, int itemIndex) { return _buildHorizontalItem(context, itemCount, itemIndex); }, ) , ) ], ); } Widget _buildHorizontalItem( BuildContext context, int carouselIndex, int itemIndex) { return Padding( padding: EdgeInsets.symmetric(horizontal: 5.0), child: Column( children: <Widget>[ Align( alignment: Alignment.centerLeft, child: Text( 'ニューアルバム', style: TextStyle(color: Colors.red, fontSize: 10, fontWeight: FontWeight.w700), ), ), Align( alignment: Alignment.centerLeft, child: Text('Sparkle', style: TextStyle(color: Colors.black, fontSize: 15, fontWeight: FontWeight.w500) ), ), Align( alignment: Alignment.centerLeft, child: Text('iri', style: TextStyle(color: Colors.grey, fontSize: 15, fontWeight: FontWeight.w500) ), ), Container( height: 226, decoration: BoxDecoration( color: Colors.grey, borderRadius: BorderRadius.all(Radius.circular(5.0)), ), ) ], ), ); } }
一つあたりのウィジェットは簡単なレイアウトで組んでみました。
これをビルドすると iOS の UIScrollView の pagingenabled
を true
にしたときのような挙動を実現できます。
この PageView を見つけるまでが非常に大変でしたが実際に使ってみること自体はとても簡単でした。 iOS の index 単位のページングスクロールを実現したい場合は是非 PageView を使ってみてください。