Flutter中如何实时监听Signature签名板是否为空?
Flutter signature 5.4.1 实时监听签名状态问题解决
问题描述
使用signature 5.4.1包时,调用_controller.isNotEmpty()或_controller.isEmpty()无法实时获取签名板的状态变化——只有应用完全刷新时,这两个方法的返回值才会更新。目前只能通过ValueListenableBuilder结合自定义ValueNotifier实现监听,但官方示例未覆盖该场景。
解决方案
优化现有实现(快速解决)
当前代码仅在onDrawEnd时更新状态,缺少清除签名时的同步逻辑。可以通过控制器的回调和清除操作同步维护ValueNotifier状态,确保实时性:
class TestSignature extends StatefulWidget { @override State<TestSignature> createState() => _TestSignatureState(); } class _TestSignatureState extends State<TestSignature> { final ValueNotifier<bool> _hasSignature = ValueNotifier<bool>(false); final SignatureController _controller = SignatureController( penStrokeWidth: 2.0, penColor: AppTheme.colorBrand0, exportBackgroundColor: Colors.transparent, exportPenColor: AppTheme.colorBrand0, ); @override void initState() { super.initState(); // 绘制开始时标记已有签名 _controller.onDrawStart = () => _hasSignature.value = true; // 绘制结束时校验实际状态(避免空笔画) _controller.onDrawEnd = () => _hasSignature.value = _controller.isNotEmpty(); } @override void dispose() { _controller.dispose(); _hasSignature.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Column( children: [ ValueListenableBuilder<bool>( valueListenable: _hasSignature, builder: (context, hasSignature, child) { return Column( children: [ Signature( key: const Key('signature'), controller: _controller, height: 150, backgroundColor: AppTheme.colorBrand1, ), // 示例:根据状态启用/禁用清除按钮 ElevatedButton( onPressed: hasSignature ? () { _controller.clear(); _hasSignature.value = false; } : null, child: const Text('清除签名'), ), ], ); }, ), ], ); } }
为什么原方法无法实时更新?
signature 5.4.1的SignatureController中,isEmpty()和isNotEmpty()是直接计算当前路径数量的同步方法,没有绑定可监听状态。当用户绘制或清除时,控制器内部状态变化不会主动通知UI刷新,只有Widget树重建时才会重新计算返回值。
进阶方案:扩展控制器实现可监听状态
如果需要更简洁的调用方式,可以扩展SignatureController,将签名状态封装为内置的ValueNotifier:
class ListenableSignatureController extends SignatureController { final ValueNotifier<bool> _isEmpty = ValueNotifier<bool>(true); ValueListenable<bool> get isEmptyListenable => _isEmpty; ListenableSignatureController({ super.penStrokeWidth, super.penColor, super.exportBackgroundColor, super.exportPenColor, }) { // 重写绘制回调同步状态 super.onDrawStart = () => _isEmpty.value = false; super.onDrawEnd = () => _isEmpty.value = super.isEmpty(); } @override void clear() { super.clear(); _isEmpty.value = true; } @override void dispose() { _isEmpty.dispose(); super.dispose(); } }
使用时直接监听控制器的内置状态:
final _controller = ListenableSignatureController( penStrokeWidth: 2.0, penColor: AppTheme.colorBrand0, ); // 在build方法中 ValueListenableBuilder<bool>( valueListenable: _controller.isEmptyListenable, builder: (context, isEmpty, child) { return Column( children: [ Signature(controller: _controller, height: 150), Text(isEmpty ? '未签名' : '已签名'), ], ); }, )
内容的提问来源于stack exchange,提问作者Rach
相关产品推荐
相关产品推荐

