🎃
Flutter いいねボタン 簡単連打対応
はじめに
いいねボタンを実装中に、タップされる度にAPIを叩きたくない。最後のタップの結果だけAPIを叩くよう実装したいと考えた際に実装した方法を記述します。
更に良い方法があれば教えてもらえると嬉しいです🏃
全コード
class LikeButton extends StatefulWidget {
const LikeButton({Key? key}) : super(key: key);
@override
LikeButtonState createState() => LikeButtonState();
}
class LikeButtonState extends State<LikeButton> {
late bool likeFlg;
late int likeCount;
Timer? timer;
@override
void initState() {
/// [likeFlg]と[likeCount]の初期化処理を行う
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
IconButton(
iconSize: 18.0,
// いいね済みの場合は赤色のアイコンを表示
icon: (likeFlg)
? const Icon(Icons.favorite, color: Colors.red)
: const Icon(Icons.favorite_border),
onPressed: () {
setState(() {
// 逆のいいねの状態を取得
likeFlg = !likeFlg;
// LikeFlgに応じて、likeCountを調整
likeFlg ? likeCount += 1 : likeCount -= 1;
});
// タイマーが存在していたら、タイマーをキャンセル
// (前回のタップから0.5秒経過前にタップされた場合は、タイマーをリスタートさせる)
if (timer != null && timer!.isActive) {
timer!.cancel();
}
timer = Timer(
// 0.5秒後に処理を行う(タップ後0.5秒経過したら、最後のタップとみなす)
const Duration(milliseconds: 500),
() async {
// likeFlgに変化があった場合のみ、変更処理を行う
if (likeFlg != initLikeFlg) {
// API処理
}
},
);
},
),
// いいね数
Text('$likeCount'),
],
);
}
}
解説
likeFlg
とlikeCount
の初期値には、APIレスポンス等の現在の値を追加します。
その後は、UIの変更のために、likeFlg
とlikeCount
はローカルの値として、APIは通さず利用します。
タイマー処理
タップ後に、再度タップされずに0.5秒経過したら、処理を行います。
-
timer
が初期化されているortimer
が起動中に、タップされた場合は、「0.5秒経過していない」とみなせるので、タイマーをキャンセルし、再度0.5秒のタイマーを起動させる。 -
timer
が起動後、タップされず0.5秒経過した場合は、「最後のタップ」 とみなし、任意の処理を行います
// タイマーが存在していたら、タイマーをキャンセル
// (前回のタップから0.5秒経過前にタップされた場合は、タイマーをリスタートさせる)
if (timer != null && timer!.isActive) {
timer!.cancel();
}
timer = Timer(
// 0.5秒後に処理を行う(タップ後0.5秒経過したら、最後のタップとみなす)
const Duration(milliseconds: 500),
() async {
// likeFlgに変化があった場合のみ、変更処理を行う
if (likeFlg != initLikeFlg) {
// API処理
}
},
);
Discussion