// Author: fruit.com.cn // 职责:协调首页三页的点击动画、最终选中目标和手势中断。 import 'package:flutter/widgets.dart'; const _transitionDuration = Duration(milliseconds: 220); /// 页面移动时保留用户最终目标,防止跨页动画途中的页面抢占高亮。 class HomeTabMotionController extends PageController { /// [onSettled] 在动画结束或被手势中断时同步实际停留页面。 HomeTabMotionController({required this.onSettled}); final ValueChanged onSettled; int? _target; int _revision = 0; bool _disposed = false; /// 供导航绘制连续位置;布局尚未建立时使用初始页。 double get pagePosition => hasClients && position.hasContentDimensions ? page ?? initialPage.toDouble() : initialPage.toDouble(); /// 点击跨页过程中只接受最终目标;拖动和稳定状态接受实际页。 bool acceptsSelection(int index) => _target == null || _target == index; /// 点击导航时平滑移动;系统减少动画时直接到位。 Future selectPage(int index, {required bool reduceMotion}) async { final revision = ++_revision; _target = index; if (!hasClients) { _target = null; return; } if (reduceMotion) { jumpToPage(index); } else { await animateToPage( index, duration: _transitionDuration, curve: Curves.easeOut, ); } if (_disposed || revision != _revision) return; _target = null; if (hasClients) onSettled(pagePosition.round()); } @override void dispose() { _disposed = true; super.dispose(); } }