Flutter

【Flutter】グラデーションをかけたDividerを作成する

記事内に商品プロモーションを含む場合があります

Flutterで区切り線などを引くときに、Dividerウィジェットを使用することがよくあります。

しかし、Dividerは便利である一方で、グラデーションをかけるなどの高度なことはできません。

本記事はグラデーションをかけたイケてるDiveiderを表示する方法の備忘録です。

通常のDiveiderはどのような実装になっているか?

まずはFlutterが用意してくれているDiveiderがどのような実装になっているかを確認してみましょう。

※興味のない方は飛ばしてください。

  @override
  Widget build(BuildContext context) {
    final DividerThemeData dividerTheme = DividerTheme.of(context);
    final double height = this.height ?? dividerTheme.space ?? 16.0;
    final double thickness = this.thickness ?? dividerTheme.thickness ?? 0.0;
    final double indent = this.indent ?? dividerTheme.indent ?? 0.0;
    final double endIndent = this.endIndent ?? dividerTheme.endIndent ?? 0.0;

    return SizedBox(
      height: height,
      child: Center(
        child: Container(
          height: thickness,
          margin: EdgeInsetsDirectional.only(start: indent, end: endIndent),
          decoration: BoxDecoration(
            border: Border(
              bottom: createBorderSide(context, color: color, width: thickness),
            ),
          ),
        ),
      ),
    );
  }

 

このようにSizedBoxとContainerの合わせ技で作成されています。

また、色を設定する箇所ではDividerの引数のcolorが設定されるため、色は単色のみとなります。

今回はグラデーションを設定したいですが、通常のDividerでは設定することができないことがわかりました。

Dividerのソースを参考にグラーデションをかけたイケてる区切り線を作成してみましょう。

自作Dividerクラスを作成する

Dividerクラスを参考に以下のように作成しました。

class CoolDivider extends StatelessWidget {
  const CoolDivider({
    Key? key,
    this.height = 16,
    this.thickness = 1,
    this.indent = 0,
    this.endIndent = 0,
    required this.gradient,
  }) : super(key: key);

  final double height;
  final double thickness;
  final double indent;
  final double endIndent;
  final LinearGradient gradient;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(
          height: height,
        ),
        Container(
          height: thickness,
          margin: EdgeInsetsDirectional.only(
            start: indent,
            end: endIndent,
          ),
          decoration: BoxDecoration(
            gradient: gradient,
          ),
        ),
      ],
    );
  }
}

 

使う側は以下のように書きます。

class CoolDividerPage extends StatelessWidget {
  const CoolDividerPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Cool Divider'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('普通のDivider'),
          Divider(
            color: Colors.blueAccent,
          ),
          Divider(
            height: 20,
            color: Colors.blueAccent,
            thickness: 3,
          ),
          SizedBox(
            height: 150,
          ),
          Text('イケてるDivider'),
          CoolDivider(
            thickness: 2,
            gradient: LinearGradient(
              begin: FractionalOffset.topLeft,
              end: FractionalOffset.bottomRight,
              colors: [
                const Color(0xff000000).withOpacity(0.7),
                const Color(0xffa7a7a7).withOpacity(0.3),
                const Color(0xff000000).withOpacity(0.7),
              ],
              stops: const [
                0.0,
                0.5,
                1.0,
              ],
            ),
          ),
          CoolDivider(
            thickness: 2,
            gradient: LinearGradient(
              begin: FractionalOffset.topLeft,
              end: FractionalOffset.bottomRight,
              colors: [
                Colors.orange,
                Colors.blueAccent,
              ],
              stops: const [
                0.0,
                1.0,
              ],
            ),
          ),
          CoolDivider(
            thickness: 2,
            gradient: LinearGradient(
              begin: FractionalOffset.topLeft,
              end: FractionalOffset.bottomRight,
              colors: [
                Colors.orange,
                Colors.pinkAccent,
                Colors.blueAccent,
              ],
              stops: const [
                0.0,
                0.5,
                1.0,
              ],
            ),
          ),
        ],
      ),
    );
  }
}

これを画面で表示すると以下のようになります。

イケてる区切り線を引くことができました!

ソース全文は以下から閲覧できます。

https://github.com/kazukios/experimental_site/blob/master/lib/views/cool_divider/cool_divider.dart

まとめ

Flutterで区切り線を引いてくれるDividerウィジェットは便利である一方で、高度なことはできません。

そのため、グラデーションなどのイケてる区切り線を引きたい場合は自作クラスを用意してあげると便利です。

 

○Flutter中級者以上にオススメの参考書

○Flutter初学者にはやはりこの参考書がオススメ