Flutter之使用Competer做防抖
在Flutter
中,Completer
可以用来实现防抖功能。防抖是用于确保时间内的所有触发被合并成单一请求。对于连续的事件触发(如用户的键盘输入、按钮的连续点击),只有在指定的延迟时间内没有再次触发事件时,才执行实际的操作。
下面是如何使用 Completer
来实现异步防抖的一个示例,代码如下:
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Drag to Sort',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<String> _items = List<String>.generate(10, (i) => 'Item $i');
bool _isReorderable = false;
@override
void initState() {
// TODO: implement initState
super.initState();
var debouncer = Debouncer(delay: Duration(seconds: 1));
// 模拟快速连续触发事件
debouncer.run(() => print('Action 1'));
debouncer.run(() => print('Action 2'));
debouncer.run(() => print('Action 3'));
// 等待一秒后执行
Future.delayed(Duration(seconds: 2), () {
debouncer.run(() => print('Action after delay'));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
// backgroundColor: Colors.blueAccent,
appBar: AppBar(
title: Text('Test'),
),
body: Column(children: [
_buildContainer(Colors.lightBlue,const Flexible(
child: Text("这是一个项目",maxLines: 1,overflow: TextOverflow.ellipsis,))),
_buildContainer(Colors.red, const Flexible(
fit: FlexFit.tight,
child: Text("这是一个项目",maxLines: 1,overflow: TextOverflow.ellipsis,))),
_buildContainer(Colors.purple, Flexible(
fit: FlexFit.tight,
child: Text("这是一个项目" * 6,maxLines: 1,overflow: TextOverflow.ellipsis,))),
_buildContainer(Colors.blue, Expanded(
child: Text("这是一个项目" * 6,maxLines: 1,overflow: TextOverflow.ellipsis,))),
],),
);
}
Container _buildContainer(Color color,Widget child) {
return Container(
height: 56,
color: color,
child: Row(
children: [
const SizedBox(width:16),
const Text("来源:"),
child,
const SizedBox(width: 8),
Container(
padding: EdgeInsets.all(5),
decoration: const BoxDecoration(
color: Colors.cyan,
borderRadius: BorderRadius.all(Radius.circular(6))
),
child: Text("项目"),
),
const SizedBox(width:16),
],
),
);
}
}
class Debouncer {
final Duration delay;
Completer? _lastCompleter;
Timer? _timer;
Debouncer({required this.delay});
void run(Function action) {
// 如果之前的操作还没有完成,取消它
if (_lastCompleter != null && !_lastCompleter!.isCompleted) {
_lastCompleter!.completeError('Cancelled');
}
_lastCompleter = Completer();
// 重置计时器
_timer?.cancel();
_timer = Timer(delay, () {
action();
_lastCompleter!.complete();
});
// 处理取消操作
_lastCompleter!.future.catchError((error) {
print('操作被取消');
});
}
}
打印如下:
在这个示例中:
Debouncer
类包含了防抖逻辑。run
方法接受一个要执行的动作,并且确保在连续调用时,只有最后一次调用会在指定的延迟后执行。- 当
run
方法被连续调用时,它会通过Completer
取消前一个还未完成的动作,并重新开始计时。 - 只有在延迟时间过去且没有新的调用时,最后一次动作才会执行。
这种方法可以有效地限制事件(如用户输入、按钮点击等)的处理频率,从而优化性能和资源利用。在实际应用中,大家可能需要根据具体情况调整延迟时间和处理逻辑。
转载自:https://juejin.cn/post/7345076635609776154