👨‍🏫

smooth_page_indicatorを使ってみる

2023/12/02に公開

🎨Overview

Webページで見かけるCSSで作ったスライドする丸がFlutterのパッケージでも作ることができるみたいです。他にもテキストと画像が表示されるCardをスライドして表示することもできる。たまに見るアプリで、スライドして、アプリの紹介があるUIですね。

https://pub.dev/packages/smooth_page_indicator

一連の組み込み効果を備えた、カスタマイズ可能なアニメーション ページ インジケーター。

こんな感じ!
https://youtube.com/shorts/fgx_ypE5Fnc?feature=share

公式を参考に設定を変更すると、インジケーターの見た目を変更することができます。effectの設定を変更すると、アニメーションやデザインを変更できます。

Padding(
	padding: const EdgeInsets.symmetric(vertical: 16),
	child: SmoothPageIndicator(
	  controller: controller,
	  count: images.length,
	  effect: const JumpingDotEffect(// ここを変更する
	    activeDotColor: Colors.blue,
	    dotColor: Colors.grey,
	    dotHeight: 16,
	    dotWidth: 16,
	    spacing: 2,
	  ),
	),
      ),

🖼️summary

早速やってみる。

こちらに完成品ございます。画像の設定とか参考にしてみてください。
https://github.com/sakurakotubaki/SmoothPageIndicator

ベースとなる全体のコードはこちら。effectプロバティの部分だけ書き換えてください。画像はフリー素材のpng画像を使っています。yamlファイルの設定が必要なので、お忘れなく。動きを見てみないとわからないので、スクリーンショットは、全て用意してないです。

ベースのコード
main.dart
import 'package:flutter/material.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';

// ignore_for_file: public_member_api_docs
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Smooth Page Indicator Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final controller = PageController(viewportFraction: 0.8, keepPage: true);

  
  Widget build(BuildContext context) {
    // imagesディレクトリにある画像を読み込む
    final images = [
      'images/0.png',
      'images/1.png',
      'images/2.png',
      'images/3.png',
      'images/4.png',
      'images/5.png',
    ];
    // 画像の名前をリストに格納する
    final title = [
      '0.png',
      '1.png',
      '2.png',
      '3.png',
      '4.png',
      '5.png',
    ];

    return Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              SizedBox(height: 16),
              SizedBox(
                height: 270, // Cardの高さを調節する
                child: PageView.builder(
                  controller: controller,
                  itemCount: images.length,
                  itemBuilder: (_, index) {
                    return Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 4),
                      child: Card(
                        elevation: 4,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(16),
                        ),
                        child: Column(
                          children: [
                            ClipRRect(
                              borderRadius: BorderRadius.circular(16),
                              // ローカルの画像を表示する
                              child: SizedBox(
                                width: 150,
                                height: 150,
                                child: Image.asset(
                                  images[index],
                                  fit: BoxFit.cover,
                                ),
                              ),
                            ),
                            const SizedBox(height: 12),
                            Text(
                              title[index],
                              style: const TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: 20,
                              ),
                            ),
                            // スライドするCSSみたいな丸を表示する
                            // Cardの中で表示
                            Padding(
                              padding: const EdgeInsets.symmetric(vertical: 16),
                              child: SmoothPageIndicator(
                                controller: controller,
                                count: images.length,
                                effect: const JumpingDotEffect(
                                  activeDotColor: Colors.blue,
                                  dotColor: Colors.grey,
                                  dotHeight: 16,
                                  dotWidth: 16,
                                  spacing: 2,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                    );
                  },
                ),
              ),
              // Cardの外で表示
              Padding(
                padding: const EdgeInsets.symmetric(vertical: 16),
                child: SmoothPageIndicator(
                  controller: controller,
                  count: images.length,
                  effect: const SlideEffect(
                    activeDotColor: Colors.blue,
                    dotColor: Colors.grey,
                    dotHeight: 16,
                    dotWidth: 16,
                    spacing: 2,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

const colors = [
  Colors.red,
  Colors.green,
  Colors.greenAccent,
  Colors.amberAccent,
  Colors.blue,
  Colors.amber,
];

横長の棒が伸びるエフェクト

Expanding Dots
Padding(
	padding: const EdgeInsets.symmetric(vertical: 16),
	child: SmoothPageIndicator(
	  controller: controller,
	  count: images.length,
	  effect: const ExpandingDotsEffect(
	    activeDotColor: Colors.blue,
	    dotColor: Colors.grey,
	    dotHeight: 16,
	    dotWidth: 16,
	    spacing: 2,
	  ),
	),
	),

くるっと回って横にスライドするエフェクト

Swap
Padding(
	padding: const EdgeInsets.symmetric(vertical: 16),
	child: SmoothPageIndicator(
	  controller: controller,
	  count: images.length,
	  effect: const SwapEffect(
	    activeDotColor: Colors.blue,
	    dotColor: Colors.grey,
	    dotHeight: 16,
	    dotWidth: 16,
	    spacing: 2,
	  ),
	),
	),

横にスライドするだけのエフェクト

Slide
Padding(
	padding: const EdgeInsets.symmetric(vertical: 16),
	child: SmoothPageIndicator(
	  controller: controller,
	  count: images.length,
	  effect: const SlideEffect(
	    activeDotColor: Colors.blue,
	    dotColor: Colors.grey,
	    dotHeight: 16,
	    dotWidth: 16,
	    spacing: 2,
	  ),
	),
	),

thoughts

今回は、スライドするエフェクトがあるUI/UXデザインを再現してみました。画像の素材はこちらのサイトのものを使いました!
これで、皆さんのアプリをおしゃれにしてみてください。

https://undraw.co/illustrations

Discussion