はじめに
SnackBar
のデザインをカスタマイズした場合、こんな感じでやたらとコードが長くなってしまいますよね。。
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
action: SnackBarAction(
label: 'Action',
onPressed: () {
// Code to execute.
},
),
content: const Text('Awesome SnackBar!'),
duration: const Duration(milliseconds: 1500),
width: 280.0, // Width of the SnackBar.
padding: const EdgeInsets.symmetric(
horizontal: 8.0, // Inner padding for SnackBar content.
),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
これをSnackBar
を表示させる部分に毎回書くのをなんとか避けられないか?を調べてみました。
SnackBar
を再利用するために外部ファイルからimportできるようにします!
SnackBarは普通のWidgetと同じように外部で作成できない
まずmy_snackbar.dart
というファイルを作成します。
my_snackbar.dart
import 'package:flutter/material.dart';
class MySnackBar extends StatelessWidget {
final String message;
MySnackBar({@required this.message});
@override
Widget build(BuildContext context) {
return SnackBar(
content: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.check,
color: Colors.white,
),
SizedBox(
width: 10,
),
Text(message),
],
),
duration: const Duration(milliseconds: 3000),
padding: const EdgeInsets.symmetric(
horizontal: 8.0, // Inner padding for SnackBar content.
),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
);
}
}
他のWidget(CardとかRowとか)ならこんなやり方でうまくいくのですが、SnackBar
はダメです
ScaffoldMessenger.of(ctx).showSnackBar(MySnackBar(message: 'Save',));
こうやって使おうとすると
The argument type 'MySnackBar' can't be assigned to the parameter type 'SnackBar'.
こんなエラーが出ます。。。
Flutterではよくある「型が違うよ!」エラーです
ではどうするか?
staticを使って実装
ScaffoldMessenger
の段階から呼び出す方法がありました!
それがstaticを使う方法です。
my_snackbar.dart
import 'package:flutter/material.dart';
class MySnackBar extends StatelessWidget {
final String message;
MySnackBar({@required this.message});
@override
Widget build(BuildContext context) {
return Container();
}
// 成功の場合のSnackBar
static show(
BuildContext context,
String message,
) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.check,
color: Colors.white,
),
SizedBox(
width: 10,
),
Text(message),
],
),
duration: const Duration(milliseconds: 3000),
padding: const EdgeInsets.symmetric(
horizontal: 8.0, // Inner padding for SnackBar content.
),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
));
}
// 失敗の場合のSnackBar
static showError(
BuildContext context,
String message,
) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.error,
color: Colors.white,
),
SizedBox(
width: 10,
),
Text(message),
],
),
duration: const Duration(milliseconds: 3000),
padding: const EdgeInsets.symmetric(
horizontal: 8.0, // Inner padding for SnackBar content.
),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
));
}
}
こんな感じで用途に応じてSnackBar
を再利用できました
👆の例では
・成功の場合はチェックマークのアイコン
・失敗の場合はエラーのアイコン
というように違いがあります。
// my_snackbar.dartをimport
import '../widgets/common_UI/my_snackbar.dart';
// 省略
.then(
// 成功の場合のSnackBar
(value) => MySnackBar.show(ctx, '追加しました!'),
)
.catchError((error) {
// // 失敗の場合のSnackBar
MySnackBar.showError(ctx, 'エラー発生!追加に失敗。。。');
});
参考