🔔

【Flutter】Stackでバッジを実装する

に公開

作るもの

アプリ開発ではお知らせの件数などを表示するバッジを実装する機会があるかと思います。今回はこのような通知アイコンに通知件数が表示されるものを作っていきます。
notification

Stackとは

バッジを作る前にまずStackについて紹介しておきます。
Stackを使うとWidgetを重ねることができ、今回の実装では通知アイコンのウィジェットと件数のウィジェットを重ね合わせて作るのでそこで使われます。またPositionedウィジェットを合わせて使うことによって位置を自由に調整することができます。

実装

まず初めにStackの説明でもあった通りにStack内に通知アイコンのウィジェットとPositionedウィジェットを置きます。件数の部分は右上に少しはみ出した形で置きたいのでtop: -10,right: -10とします。

Stack(
    children: [
      const Icon(
        Icons.notifications,
        size: 45,
      ),
      Positioned(
        top: -10,
        right: -10,
        child: Container(
          width: 30,
          height: 30,
          decoration: const BoxDecoration(
            color: Colors.blueGrey,
            shape: BoxShape.circle,
          ),
          child: const Center(
            child: Text(
              '1',
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
      ),
    ],
),

しかし、そのまま重ねるとはみだし部分が切り取られてしまいます。その場合はどのようにすればいいのでしょうか?
notification

はみ出し部分が切り取られないようにするには

はみ出し部分を消すにはClip.noneを指定してあげる必要があります。理由としてはStackウィジェットのclipBehaviorプロパティはClip.hardEdgeという値がデフォルトで指定されており、あらかじめウィジェットが親要素からはみ出した場合の挙動が決められているからです。

Stack(
    // ここに追加
    clipBehavior: Clip.none, 
    children: [
      const Icon(
        Icons.notifications,
        size: 45,
      ),
      Positioned(
        top: -10,
        right: -10,
        child: Container(
          width: 30,
          height: 30,
          decoration: const BoxDecoration(
            color: Colors.blueGrey,
            shape: BoxShape.circle,
          ),
          child: const Center(
            child: Text(
              '1',
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
      ),
    ],
),

というわけでClip.noneを指定するとこのように通知アイコンに通知件数が表示されるバッジを作成することができます。

notification

終わり

お知らせの件数などを表示するバッジを実装をしましたがそこまで難しくはなかったかと思います。また、badgesのような便利なパッケージもあり詳細に設定できるので、特に理由がなければ要件に応じて使い分けるのが良いかと思います。
https://pub.dev/packages/badges

GitHubで編集を提案

Discussion