LoginSignup
7
0

More than 1 year has passed since last update.

Flutterで半透明のBottomSheetを実装

Posted at

Flutterで半透明BottomSheetを実装しよう!

背景を透かしたBottomSheetを実装しようと思いましたが、なかなか情報がない中実装してみたので備忘録として記録します。

いい感じに使えたら少しおしゃれなボトムシートが実装できるかも?しれないので参考になれば幸いです。

完成コード

コード(主要部分)

まずは、ボトムシートを出し入れするクラスの作成です

class AppRouter {
  static final AppRouter _singleton = AppRouter._internal();
  factory AppRouter() {
    return _singleton;
  }
  AppRouter._internal();

  Future<dynamic> showCustomBottomSheet(BuildContext context, Widget body) {
    return showModalBottomSheet(
      backgroundColor: Colors.transparent,
      context: context,
      isScrollControlled: true,
      builder: (context) {
        return CustomBottomSheet( // <= 後述で説明します
          body: body,
        );
      },
    );
  }
}

使い方

AppRouter().showCustomBottomSheet(
    context,
    Container( // <= シート本体に入れたいウィジェット
      ...
    ),
);

次に、ボトムシートのウィジェット部分についてです。
デフォルトのウィジェットではなく

/// ボトムシートの土台となるウィジェット
class CustomBottomSheet extends StatelessWidget {
  const CustomBottomSheet({
    super.key,
    required this.body,
  });

  final Widget body;

  static const cornerRadius = 20.0;
  static Color maskColor = Colors.black45.withOpacity(0.5); // 透過した背景
  static ImageFilter filter = ImageFilter.blur(sigmaX: 20, sigmaY: 20); // 背景ぼかし

  @override
  Widget build(BuildContext context) {
    // 
    return ClipRRect(
      borderRadius: const BorderRadius.vertical(
        top: Radius.circular(cornerRadius),
      ),
      child: Container(
        padding: const EdgeInsets.only(top: 5.0),
        decoration: BoxDecoration(
          color: maskColor,
          borderRadius: const BorderRadius.vertical(
            top: Radius.circular(cornerRadius),
          ),
        ),
        child: Stack(
          children: [
            // シート上部のインディケーター
            const Positioned.fill(
              child: Align(
                alignment: Alignment.topCenter,
                child: _DragIndicator(),
              ),
            ),
            body,
          ],
        ),
      ),
    );
  }
}

/// シート上部に設置したドラッグインジケーター
class _DragIndicator extends StatelessWidget {
  const _DragIndicator({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 35,
      height: 4,
      decoration: BoxDecoration(
        color: Colors.white54,
        borderRadius: BorderRadius.circular(2),
      ),
    );
  }
}

実装後イメージ

Githubのコードを実行していただくと以下のようにサンプルが閲覧できます。

sample_capture.gif

以上です!

7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0