pd_cooldown 0.0.2
pd_cooldown: ^0.0.2 copied to clipboard
A professional Flutter debounce and throttle plugin providing complete debounce/throttle solutions with built-in UI components.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:pd_cooldown/pd_cooldown.dart';
void main() {
runApp(const MaterialApp(
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
String _message = '点击按钮测试防抖节流功能';
int _counter = 0;
int _throttleClickCount = 0;
int _debounceClickCount = 0;
final _pdCooldownPlugin = PdCooldown();
late final PDCooldown _cooldown;
@override
void initState() {
super.initState();
debugPrint('🚀 [示例应用] 初始化开始');
debugPrint('📦 [插件信息] PD Cooldown Plugin - 防抖节流功能演示');
initPlatformState();
_cooldown = PDCooldown.withDefaults(
cooldownDuration: const Duration(seconds: 3),
);
debugPrint('⚙️ [PDCooldown] 核心冷却组件初始化完成,冷却时间: 3秒');
debugPrint('🎮 [功能说明] 核心功能:防止重复执行,UI组件:节流按钮、防抖按钮');
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
debugPrint('📱 [平台检测] 开始获取平台版本信息...');
// Platform messages may fail, so we use a try/catch PlatformException.
// We also handle the message potentially returning null.
try {
platformVersion = await _pdCooldownPlugin.getPlatformVersion() ??
'Unknown platform version';
debugPrint('✅ [平台检测] 成功获取平台版本: $platformVersion');
} on PlatformException catch (e) {
platformVersion = 'Failed to get platform version.';
debugPrint('❌ [平台检测] 获取平台版本失败: $e');
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) {
debugPrint('⚠️ [生命周期] Widget已卸载,跳过状态更新');
return;
}
setState(() {
_platformVersion = platformVersion;
});
debugPrint('🔄 [状态更新] 平台版本信息已更新到UI');
}
Future<void> _handleCooldownAction() async {
debugPrint('🎯 [冷却测试] 用户点击冷却功能按钮');
final result = await _cooldown.execute<String>(() async {
debugPrint('⚡ [业务逻辑] 开始执行异步操作...');
// 模拟异步操作
await Future.delayed(const Duration(milliseconds: 500));
_counter++;
final resultMsg = '操作成功执行 #$_counter';
debugPrint('✅ [业务逻辑] 异步操作完成: $resultMsg');
return resultMsg;
}, onCooldown: (remaining) {
final cooldownMsg = '冷却中,剩余时间: ${remaining.inSeconds}秒';
debugPrint('❄️ [冷却状态] $cooldownMsg');
setState(() {
_message = cooldownMsg;
});
});
if (result != null) {
debugPrint('🎉 [执行结果] 操作成功完成: $result');
setState(() {
_message = result;
});
} else {
debugPrint('🚫 [执行结果] 操作被冷却机制阻止');
}
}
@override
Widget build(BuildContext context) {
debugPrint('🎨 [UI渲染] 开始构建示例应用界面');
debugPrint('📋 [功能清单] 1.核心冷却功能(3秒) 2.节流按钮(2秒) 3.防抖按钮(800ms)');
debugPrint('📊 [状态统计] 冷却执行次数: $_counter, 节流点击: $_throttleClickCount, 防抖点击: $_debounceClickCount');
return Scaffold(
appBar: AppBar(
title: const Text('PD Cooldown 示例'),
backgroundColor: Colors.blue,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'运行平台: $_platformVersion',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 32),
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
'防抖节流核心功能测试',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 16),
Text(
_message,
style: Theme.of(context).textTheme.bodyLarge,
textAlign: TextAlign.center,
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
debugPrint('🎯 [用户交互] 用户准备测试核心冷却功能');
_handleCooldownAction();
},
child: const Text('测试冷却功能 (3秒冷却)'),
),
],
),
),
),
const SizedBox(height: 32),
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
'防抖按钮组件测试',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () {
setState(() {
_throttleClickCount++;
});
final now = DateTime.now();
debugPrint('👆 [节流按钮] 检测到点击 #$_throttleClickCount,时间: ${now.toString().substring(11, 23)}');
},
child: PDThrottleButton(
buttonType: PDButtonType.elevated,
debounceDuration: const Duration(seconds: 2),
onPressed: () {
final now = DateTime.now();
debugPrint('🔥 [节流按钮] 按钮被点击,时间: ${now.toString().substring(11, 23)},节流时间: 2秒');
debugPrint('💡 [节流说明] 节流模式:立即执行第一次点击,后续点击在冷却期内被忽略');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('节流按钮被点击 #$_throttleClickCount - 2秒内再次点击将被忽略'),
duration: const Duration(seconds: 2),
),
);
},
onCooldown: (remaining) {
debugPrint('🧊 [节流按钮] 冷却中,剩余时间: ${remaining.inMilliseconds}ms');
},
logger: DefaultCooldownLogger(),
child: const Text('节流按钮'),
),
),
GestureDetector(
onTap: () {
setState(() {
_debounceClickCount++;
});
final now = DateTime.now();
debugPrint('👆 [防抖按钮] 检测到点击 #$_debounceClickCount,时间: ${now.toString().substring(11, 23)}');
},
child: PDDebounceButton(
buttonType: PDButtonType.elevated,
debounceDuration: const Duration(milliseconds: 800),
onPressed: () {
final now = DateTime.now();
debugPrint('⚡ [防抖按钮] 防抖延迟结束,执行按钮操作,时间: ${now.toString().substring(11, 23)}');
debugPrint('💡 [防抖说明] 防抖模式:延迟执行,连续点击会重置计时器,只执行最后一次');
debugPrint('📊 [防抖统计] 总点击次数: $_debounceClickCount,实际执行次数: 1');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('防抖按钮被点击 - 合并了$_debounceClickCount次点击'),
duration: const Duration(seconds: 2),
),
);
// 重置计数器
setState(() {
_debounceClickCount = 0;
});
},
logger: DefaultCooldownLogger(),
child: const Text('防抖按钮'),
),
),
],
),
],
),
),
),
],
),
),
);
}
}