宮沢賢治のオールナイトニッポン

アプリ開発/プログラミング学習における厄介事を垂れ流します。flutter/dart/python...

インジケータつきのカルーセルスライダー/Carousel Slider with Indicator 【Flutter】

ルーセルスライダーにインデックスインジケータ(?)を実装したい。

開発中のカルーセルスライダーをいじる機会があったので記録に残します。 下記のパッケージはすごく充実していて、お手軽にカルーセルを実装できます。

pub.dev

f:id:teruponn56:20210321121112p:plain

上記のデモの実装は下記になります。インジケータ部分において、現在表示されていもののインデックスが黒丸で表現されています。

class _CarouselWithIndicatorState extends State<CarouselWithIndicatorDemo> {
  int _current = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Carousel with indicator demo')),
      body: Column(
          children: [
            CarouselSlider(
              items: imageSliders,
              options: CarouselOptions(
                  autoPlay: true,
                  enlargeCenterPage: true,
                  aspectRatio: 2.0,
                  onPageChanged: (index, reason) {
                    setState(() {
                      _current = index;
                    });
                  }
              ),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: imgList.map((url) {
                int index = imgList.indexOf(url);
                return Container(
                  width: 8.0,
                  height: 8.0,
                  margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    color: _current == index
                        ? Color.fromRGBO(0, 0, 0, 0.9)
                        : Color.fromRGBO(0, 0, 0, 0.4),
                  ),
                );
              }).toList(),
            ),
          ]
      ),
    );
  }
}

グレーや黒の丸で表現されている上記のインジケータをいじり、インデックスの数字で表現をしたいと思います。 上記コードのインジケータ実装部ではRow()の子要素としてContainer()で丸を表現したものを返しているだけでしたが、下記のようにStackでまとめて、丸の上からIndexの数字を重ねてやります。

Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: imgList.map((url) {
            int index = imgList.indexOf(url);
            return Stack(children: [
              Container(
                width: 36,
                height: 36,
                margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: _current == index ? Colors.blue : Colors.grey[350],
                ),
              ),
              Container(
                  margin: EdgeInsets.fromLTRB(2, 13, 2, 7),
                  width: 36,
                  height: 36,
                  child: Text('${index + 1}',
                      textAlign: TextAlign.center,
                      style: TextStyle(
                          color: Colors.black,
                          fontSize: 24,
                          fontWeight: FontWeight.bold)))
            ]);
          }).toList(),
        )

こんなかんじで実装できました☺

f:id:teruponn56:20210601130833g:plain

下記のレポジトリにあるので、見てやってください😊 github.com