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のコードを実行していただくと以下のようにサンプルが閲覧できます。
以上です!