carousel_sliderとは
flutterのパッケージの一種で、画像やウィジェットをスライドショーとして動かすことができます。
画像を複数枚並べたい時などに使われます。
使用環境
VScode バージョン: 1.84.2
Flutter バージョン: 3.76.0
carousel_slider: ^4.2.1
実装
動作画面と実装コードです。
各ウィジェットのレイアウトが分かるように色分けをしました。
以下実装コードです。(抜粋)
final carouselSliderNumberProvider = StateProvider<int>((ref) => 0);
class ImageSlider extends ConsumerWidget {
ImageSlider({Key? key}) : super(key: key);
final imageList = [
'「な」の画像のURL',
'「ナ」の画像のURL',
'「こ」の画像のURL',
'「し」の画像のURL'
];
@override
Widget build(BuildContext context, WidgetRef ref) {
int carouselSliderNumber = ref.watch(carouselSliderNumberProvider);
-----
省略
-----
child: CarouselSlider.builder(
options: CarouselOptions(
height: 300,
initialPage: 0,
viewportFraction: 1,
enlargeCenterPage: true,
onPageChanged: (index, reason) {
ref.watch(carouselSliderNumberProvider.notifier).state
= carouselSliderNumber = index;
}),
itemCount: imageList.length,
itemBuilder: (context, index, realIndex) {
final path = imageList[index];
return buildImage(path, index);
},
),
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: imageList.map((url) {
int index = imageList.indexOf(url);
return Container(
width: 15,
height: 15,
margin:const EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: carouselSliderNumber == index
? const Color.fromRGBO(115, 137, 187, 1)
: const Color.fromRGBO(115, 137, 187, 0.4),
),
);
}).toList(),
),
],
)),
);
}
-----
省略
解説
final carouselSliderNumberProvider = StateProvider<int>((ref) => 0);
int carouselSliderNumber = ref.watch(carouselSliderNumberProvider);
現在のスライドショーの番号をRiverpodのStateProviderで監視します。
配列のインデックスは0から始まるので初期値は0にします。
監視している数字をcarouselSliderNumberと定義します。
final imageList = [
'「な」の画像のURL',
'「ナ」の画像のURL',
'「こ」の画像のURL',
'「し」の画像のURL'
];
表示させたい画像のURLをリストにまとめておきます。
child: CarouselSlider.builder(
options: CarouselOptions(
height: 300,
initialPage: 0,
viewportFraction: 1,
enlargeCenterPage: true,
onPageChanged: (index, reason) {
ref.watch(carouselSliderNumberProvider.notifier).state
= carouselSliderNumber = index;
CarouselSlider.builderでスライダーを描画
CarouselOptionsでスライダーの動きなどをカスタムできます。
onPageChanged: スライドが切り替わった時の動作
notifireで現在の配列番号の更新を依頼、state(状態)を切り替わったスライド番号に変更する。
itemCount: imageList.length,
itemBuilder: (context, index, realIndex) {
final path = imageList[index];
return buildImage(path, index);
itemBuilder:スライダーに表示したい画像を描画
itemCount:表示したいアイテム数を指定
imageList.length つまりImageListの配列全て表示させる(今回は4つ)
return buildImageで画像データが入ったウィジェットを呼び出す(内容はソースコード参照)
return Container(
width: 15,
height: 15,
margin:const EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: carouselSliderNumber == index
? const Color.fromRGBO(115, 137, 187, 1)
: const Color.fromRGBO(115, 137, 187, 0.4),
),
);
ここでスライダー下の●を作成
三項演算子を使用し、スライダーの動きと連動して●の色の切り替えを行なっている
条件式 ( carouselSliderNumber が index(0~3の配列番号)と等しい )
? ( trueなら濃い青 ) : ( falseなら薄い青 ) になる
つまり、今表示されているスライドの●が濃い青色になり、それ以外の●は薄い青色になる
ソースコード
全体のソースコードになります。
final carouselSliderNumberProvider = StateProvider<int>((ref) => 0);
class ImageSlider extends ConsumerWidget {
ImageSlider({Key? key}) : super(key: key);
final imageList = [
'「な」の画像のURL',
'「ナ」の画像のURL',
'「こ」の画像のURL',
'「し」の画像のURL'
];
@override
Widget build(BuildContext context, WidgetRef ref) {
int carouselSliderNumber = ref.watch(carouselSliderNumberProvider);
return Scaffold(
backgroundColor: const Color.fromRGBO(254, 243, 239, 1),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('カルーセルスライダーで[なナこし]と表示'),
const SizedBox(height: 20),
Container(
color: const Color.fromRGBO(214, 228, 231, 1),
child: CarouselSlider.builder(
options: CarouselOptions(
height: 300,
initialPage: 0,
viewportFraction: 1,
enlargeCenterPage: true,
onPageChanged: (index, reason) {
ref.watch(carouselSliderNumberProvider.notifier).state
= carouselSliderNumber = index;
}),
itemCount: imageList.length,
itemBuilder: (context, index, realIndex) {
final path = imageList[index];
return buildImage(path, index);
},
),
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: imageList.map((url) {
int index = imageList.indexOf(url);
return Container(
width: 15,
height: 15,
margin:const EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: carouselSliderNumber == index
? const Color.fromRGBO(115, 137, 187, 1)
: const Color.fromRGBO(115, 137, 187, 0.4),
),
);
}).toList(),
),
],
)),
);
}
//表示したい画像のウィジェット
Widget buildImage(path, index) {
return Container(
color: const Color.fromRGBO(166, 190, 214, 1),
child: Image.network(
path,
fit: BoxFit.cover,
),
);
}
}
いかがだったでしょうか?
ご意見、ご感想ありましたらお気軽にコメントしてください。
carousel_sliderを使うとスライドショーが手軽に実装でき、ECアプリなどの商品紹介に使えそうですよね。
【参考文献】
コメント