为ReorderableListView头部实现吸附效果时animateTo失效问题
解决ReorderableListView头部滚动吸附动画不生效的问题
你的问题核心是滚动监听器被频繁触发,导致animateTo的动画被不断打断,同时缺少动画执行状态的判断,重复调用动画会被系统忽略。以下是具体修复方案:
1. 添加动画状态锁,避免重复触发
在State类中新增一个布尔变量,标记当前是否有滚动动画在执行:
bool _isAnimating = false;
2. 修改监听器逻辑,加入状态判断
更新jobWidgetListener,仅在无动画执行时触发新的滚动动画,并在动画完成后重置状态:
void jobWidgetListener() { if (_reorderScrollController.hasClients && !_isAnimating) { final currentExtentBefore = _reorderScrollController.position.extentBefore; if (currentExtentBefore < _processItemWidth * 0.8) { print('滚动到顶部'); _isAnimating = true; _reorderScrollController.animateTo( 0.0, duration: const Duration(milliseconds: 350), curve: Curves.easeOut, ).whenComplete(() => _isAnimating = false); } else if (currentExtentBefore < _processItemWidth) { print('滚动到头部位置'); _isAnimating = true; _reorderScrollController.animateTo( _processItemWidth + 8.0, duration: const Duration(milliseconds: 350), curve: Curves.easeOut, ).whenComplete(() => _isAnimating = false); } } }
3. 额外优化:排除拖拽状态下的触发
ReorderableListView拖拽列表项时会触发滚动事件,此时执行吸附动画会干扰拖拽体验,可以加入拖拽状态判断:
// 在判断条件中添加拖拽状态排除 if (_reorderScrollController.hasClients && !_isAnimating && !_reorderScrollController.position.isScrollingNotifier.value) { // ... 原有逻辑 }
4. 完善控制器生命周期管理
在组件销毁时释放控制器资源,避免内存泄漏:
@override void dispose() { _reorderScrollController.removeListener(jobWidgetListener); _reorderScrollController.dispose(); super.dispose(); }
修改后,动画不会被频繁打断,能够正常执行滚动吸附效果。
内容的提问来源于stack exchange,提问作者pbs
相关产品推荐
相关产品推荐

