关于Flutter防止连续点击问题,看其他文章都是延迟触发操作的思路,这样多少会感觉有点卡,如果一直点击的话,就会一直不响应事件。
两种方式, 第一种是不区分事件,统一控制事件的响应间隔
///使用
LwDeBouncer.run((){
print("lw----触发任务==}${DateTime.now()}");
},customInterval: 500);
第二种是区分事件,只有相同的事件才会控制响应间隔,不同事件之间互不影响。
///使用
LwDeBouncer.call(() {
print("lw----触发任务index:$index");
},
tag: index.toString(),
);
import 'dart:async';
/// 防止连续点击
class LwDeBouncer {
static Timer? _timer;
/// 上次执行时间
static int lastMilliseconds = 0;
/// 事件间隔
static int actionInterval = 1000;
static List<String> actionIds = [];
static int emptyIndex = 0;
/// 不区分点击事件,统一事件响应间隔时间
static run(Function action, {int customInterval = 0}) {
if (DateTime.now().millisecondsSinceEpoch - lastMilliseconds <
(customInterval == 0 ? actionInterval : customInterval)) return;
action();
lastMilliseconds = DateTime.now().millisecondsSinceEpoch;
}
/// 区分事件,只有相同的事件,才会控制间隔时间
/// tag:外部调用相同函数,触发的不同事件,(例如:ListView的item事件,可以通过添加tag进行区分,)
static call(Function action, {String? tag}) {
String actionId = getFunctionIdentify() + (tag != null ? '_$tag' : '');
if (actionIds.contains(actionId)) return;
actionIds.add(actionId);
action();
startTimer();
}
static startTimer() {
emptyIndex = 0;
_timer ??= Timer.periodic(Duration(milliseconds: actionInterval), (t) {
if (actionIds.isNotEmpty) {
String tem = actionIds.removeAt(0);
} else {
if (emptyIndex != 0) emptyIndex = t.tick;
}
if (actionIds.isEmpty && emptyIndex < t.tick) {
_timer?.cancel();
_timer = null;
}
});
}
static getFunctionIdentify() {
String identify = DateTime.now().millisecondsSinceEpoch.toString();
StackTrace stackTrace = StackTrace.current;
List<String> frames = stackTrace.toString().split('\n');
if (frames.length < 3) return identify;
String funcLine = frames[2];
if (funcLine.contains('(') && funcLine.contains(')')) {
funcLine = funcLine.substring(funcLine.indexOf('(') + 1, funcLine.indexOf(')'));
}
return funcLine;
}
}
如果有什么问题,望相互交流