この記事でやりたいこと・紹介すること
ボタンを押した後の処理を実行中は、ボタンを押せないようにするボタンを作成して、ユーザーが連打や実行中に比較的短い時間内でボタンを再度タップする動作等をしても二重で処理が発生しないようにする
実施した概要
ボタンクラスのラッパークラスを作成して、処理中はボタンの"onPressed"パラメータにNullを渡すことでタップ動作を無効にする。
上記の実装をすることで、容易に連打防止対応をしたボタンをコード全体で簡単に何度も使用することができます。
実際の方法とソースコード
実際の導入方法を紹介します。
ボタンクラスのラッパークラスを作成
ボタンクラスのラッパークラスであるWaitableElevatedButton
クラスとWaitableOutlinedButton
クラスを作成
以下のファイルを任意の場所に作成します。
私は、基本的にUtilディレクトリ等を作成して、その配下に以下のwaitable_button.dart
クラスを作成します。
waitable_button.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class WaitableElevatedButton extends StatefulWidget {
WaitableElevatedButton({
required this.onPressed,
required this.child,
this.style,
super.key,
});
@override
createState() => _WaitableElevatedButtonState();
final AsyncCallback? onPressed;
final ButtonStyle? style;
final Widget child;
}
class _WaitableElevatedButtonState extends State<WaitableElevatedButton> {
bool _waiting = false;
@override
Widget build(BuildContext context) {
return ElevatedButton(
style: widget.style,
onPressed: widget.onPressed == null || _waiting
? null
: () async {
setState(() => _waiting = true);
await widget.onPressed!();
setState(() => _waiting = false);
},
child: widget.child,
);
}
}
class WaitableOutlinedButton extends StatefulWidget {
WaitableOutlinedButton({
required this.onPressed,
required this.child,
this.style,
super.key,
});
@override
createState() => _WaitableOutlinedButtonState();
final AsyncCallback? onPressed;
final ButtonStyle? style;
final Widget child;
}
class _WaitableOutlinedButtonState extends State<WaitableOutlinedButton> {
bool _waiting = false;
@override
Widget build(BuildContext context) {
return OutlinedButton(
style: widget.style,
onPressed: widget.onPressed == null || _waiting
? null
: () async {
setState(() => _waiting = true);
await widget.onPressed!();
setState(() => _waiting = false);
},
child: widget.child,
);
}
}
コード内での利用方法
後は上記のWaitableElevatedButton
クラスとWaitableOutlinedButton
クラスを通常のElevatedButton
のように記述することで連打防止ボタンが実装できます。
変更例.dart
- child: ElevatedButton( //元のクラス
+ child: WaitableElevatedButton( //新しいクラス
使用例.dart
ElevatedButton(
child: const Text('Button'),
style: ElevatedButton.styleFrom(
primary: Colors.yellow,
onPrimary: Colors.black,
shape: BeveledRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
onPressed: () async {
// 何らかの処理。(下記は単純に10ミリ秒Delayをさせているだけ)
await Future.delayed(Duration(milliseconds: 10));
},
),
参考記事