BlocBuilder中DraggableScrollableController调用animateTo报错及实现咨询
问题分析与解决方案
错误原因
你遇到的断言错误确实是因为**在build函数中直接调用animateTo**导致的:
DraggableScrollableSheet的builder回调执行时,控制器还未完成与sheet的绑定,此时isAttached为false,触发了框架的断言检查。
解决方案
1. 延迟执行动画到UI帧构建完成后
使用WidgetsBinding.instance.addPostFrameCallback,在当前UI帧构建完成后再调用animateTo,此时控制器已经成功附着到sheet上。
2. 结合Bloc状态控制动画触发时机
只在特定的状态变化(比如页面跳转对应的状态)下执行动画,避免每次build都重复触发。
修改后的代码示例
return BlocBuilder<FrontPageContainerHeightCubit, FrontPageContainerHeightCubitState>( builder: (context, state) { final cubit = context.read<FrontPageContainerHeightCubit>(); // 仅在需要触发动画的状态下执行(根据你的业务逻辑调整判断条件) final needAnimate = state is TargetPageJumpState; return Container( alignment: Alignment.bottomCenter, child: DraggableScrollableSheet( initialChildSize: services.screen.frontPageContainer .asPercentage(state.frontPageContainerHeight), minChildSize: services.screen.frontPageContainer .asPercentage(state.frontPageContainerHeight), maxChildSize: min( 1.0, max( services.screen.frontPageContainer .asPercentage(state.frontPageContainerHeight), services.screen.frontPageContainer.maxPercentage, ), ), controller: cubit.draggableScrollableController, builder: (context, scrollController) { cubit.setScrollableController(scrollController); if (needAnimate) { // 延迟到当前UI帧构建完成后执行动画 WidgetsBinding.instance.addPostFrameCallback((_) { if (cubit.draggableScrollableController.isAttached) { cubit.draggableScrollableController.animateTo( services.screen.frontPageContainer.asPercentage( services.screen.frontPageContainer.midHeight, ), duration: const Duration(seconds: 10), curve: Curves.easeInOut, ); } }); } return Stack( alignment: Alignment.bottomCenter, children: const [FrontDrop(), utilities.beamer.front()], ); }, ), ); }, );
额外注意事项
- 增加
isAttached判断,避免极端场景下(如sheet已被销毁)再次触发错误。 - 确保
needAnimate的判断逻辑准确,仅在页面跳转等需要触发动画的场景下执行,防止不必要的重复动画。
内容的提问来源于stack exchange,提问作者MetaStack
相关产品推荐
相关产品推荐

