🧪
base classの使用例
なかなか思いつかない?
Dart3.0から追加された base class。使い道がわからない。Flutterで使うならWidtgetだと思うが。
base classは継承して使うにはfinalをつけます。つけないとエラーが出てしまう。最近副業でスナックバーをコンポーネント化して汎用性の高いものにしたいと言われた。
そういえばエラー用しか作ってない。こちらがサンプル。ベースクラスを作成して継承してロジックを持たせる。これでメッセージ出すだけのスナックバーとエラー用のスナックバーを作れる。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Custom SnackBar Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Custom SnackBar Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
CustomSnackBar.showNormal(
context: context,
message: 'This is a normal message',
);
},
child: const Text('Show Normal SnackBar'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
CustomSnackBar.showError(
context: context,
message: 'This is an error message',
);
},
child: const Text('Show Error SnackBar'),
),
],
),
),
);
}
}
enum SnackBarType { normal, error }
base class BaseCustomSnackBar {
const BaseCustomSnackBar({
required this.message,
required this.type,
});
final String message;
final SnackBarType type;
Color get backgroundColor => type == SnackBarType.normal
? Colors.blue.shade900
: Colors.red.shade900;
Color get textColor => Colors.white;
IconData get icon => type == SnackBarType.normal
? Icons.info_outline
: Icons.error_outline;
SnackBar build() {
return SnackBar(
content: Row(
children: [
Icon(icon, color: textColor),
const SizedBox(width: 8),
Expanded(
child: Text(
message,
style: TextStyle(color: textColor),
),
),
],
),
backgroundColor: backgroundColor,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
);
}
}
final class CustomSnackBar extends BaseCustomSnackBar {
const CustomSnackBar({
required super.message,
required super.type,
});
static void showNormal({
required BuildContext context,
required String message,
}) {
_show(context: context, message: message, type: SnackBarType.normal);
}
static void showError({
required BuildContext context,
required String message,
}) {
_show(context: context, message: message, type: SnackBarType.error);
}
static void _show({
required BuildContext context,
required String message,
required SnackBarType type,
}) {
final snackBar = CustomSnackBar(message: message, type: type).build();
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}
実行結果
ボタンのコンポーネントだとこんな感じか。いつもはこんな書き方しませんが、使えそうだったら試してみたい。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Custom Button Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Custom Button Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
PrimaryButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('Primary button pressed!'),
backgroundColor: Colors.blue,
behavior: SnackBarBehavior.floating,
),
);
},
child: const Text('Primary Button'),
),
const SizedBox(height: 20),
SecondaryButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('Secondary button pressed!'),
backgroundColor: Colors.red,
behavior: SnackBarBehavior.floating,
action: SnackBarAction(
label: 'OK',
textColor: Colors.white,
onPressed: () {},
),
),
);
},
child: const Text('Secondary Button'),
),
],
),
),
);
}
}
base class BaseButton extends StatelessWidget {
const BaseButton({
required this.onPressed, required this.child, required this.backgroundColor, required this.textColor, super.key,
});
final VoidCallback? onPressed;
final Widget child;
final Color backgroundColor;
final Color textColor;
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: backgroundColor,
foregroundColor: textColor,
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: child,
);
}
}
final class PrimaryButton extends BaseButton {
const PrimaryButton({
required super.onPressed, required super.child, super.key,
}) : super(
backgroundColor: Colors.blue,
textColor: Colors.white,
);
}
final class SecondaryButton extends BaseButton {
const SecondaryButton({
required super.onPressed, required super.child, super.key,
}) : super(
backgroundColor: Colors.red,
textColor: Colors.white,
);
}
最後に
Flutter3, Dart3.0新しい機能が気がついたら出ている。毎日勉強していないと追いつけません💦
最近は汎用的はWidgetを作れいだろうかと仲間と研究中🧪
Discussion