使用Scrollbar时,提示“flutter: Interceptor: ══╡ EXCEPTION CAUGHT BY ANIMATION LIBRARY ╞═══”

出现的问题:

问题如图所示,我写了一个小例子,来学习SingleChildScrollView。代码很简单,这里给出:

class _ScrollTest extends StatelessWidget{
  
  
  Widget build(BuildContext context){
    String str = "asdafdsfsdgee";
    return Scrollbar(
      interactive: true,
      child: SingleChildScrollView(
        primary: true, //
        padding: const EdgeInsets.all(16.0),
        child: Center(
          child: Column(
            children: str.split("").map((e) => Text(e,)).toList(),
          ),
        ),
      ),
    );
  }
}

执行后不报错,然后,当鼠标在界面上滑动时,它会报错如下:

flutter: Interceptor: ══╡ EXCEPTION CAUGHT BY ANIMATION LIBRARY ╞══════════════════════
The following assertion was thrown while notifying status
listeners for AnimationController:
The Scrollbar's ScrollController has no ScrollPosition attached.
A Scrollbar cannot be painted without a ScrollPosition.
The Scrollbar attempted to use the PrimaryScrollController. This
ScrollController should be associated with the ScrollView that
the Scrollbar is being applied to.When ScrollView.scrollDirection
is Axis.vertical on mobile platforms will automatically use the
PrimaryScrollController if the user has not provided a
ScrollController. To use the PrimaryScrollController explicitly,
set ScrollView.primary to true for the Scrollable widget.

When the exception was thrown, this was the stack:
#0      RawScrollbarState._debugCheckHasValidScrollPosition.<anonymous closure> (package:flutter/src/widgets/scrollbar.dart:1459:9)
#1      RawScrollbarState._debugCheckHasValidScrollPosition (package:flutter/src/widgets/scrollbar.dart:1484:6)
#2      RawScrollbarState._validateInteractions (package:flutter/src/widgets/scrollbar.dart:1428:14)
#3      AnimationLocalStatusListenersMixin.notifyStatusListeners (package:flutter/src/animation/listener_helpers.dart:240:19)
#4      AnimationController._checkStatusChanged (package:flutter/src/animation/animation_controller.dart:850:7)
#5      AnimationController._startSimulation (package:flutter/src/animation/animation_controller.dart:781:5)
#6      AnimationController._animateToInternal (package:flutter/src/animation/animation_controller.dart:644:12)
#7      AnimationController.forward (package:flutter/src/animation/animation_controller.dart:493:12)
#8      RawScrollbarState._handleScrollNotification (package:flutter/src/widgets/scrollbar.dart:1822:37)
#9      _NotificationElement.onNotification (package:flutter/src/widgets/notification_listener.dart:130:38)
#10     _NotificationNode.dispatchNotification (package:flutter/src/widgets/framework.dart:3320:18)
#11     _NotificationNode.dispatchNotification (package:flutter/src/widgets/framework.dart:3323:13)
#12     _NotificationNode.dispatchNotification (package:flutter/src/widgets/framework.dart:3323:13)
#13     _NotificationNode.dispatchNotification (package:flutter/src/widgets/framework.dart:3323:13)
#14     Element.dispatchNotification (package:flutter/src/widgets/framework.dart:4942:24)
#15     Notification.dispatch (package:flutter/src/widgets/notification_listener.dart:60:13)
#16     ScrollActivity.dispatchScrollUpdateNotification (package:flutter/src/widgets/scroll_activity.dart:104:92)
#17     ScrollPosition.didUpdateScrollPositionBy (package:flutter/src/widgets/scroll_position.dart:1023:15)
#18     ScrollPositionWithSingleContext.pointerScroll (package:flutter/src/widgets/scroll_position_with_single_context.dart:234:7)
#19     ScrollableState._handlePointerScroll (package:flutter/src/widgets/scrollable.dart:938:16)
#20     PointerSignalResolver.resolve (package:flutter/src/gestures/pointer_signal_resolver.dart:103:32)
#21     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:501:29)
#22     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:475:22)
#23     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:425:11)
#24     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:420:7)
#25     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:383:5)
#26     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:330:7)
#27     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:299:9)
#31     _invoke1 (dart:ui/hooks.dart:330:10)
#32     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:429:7)
#33     _dispatchPointerDataPacket (dart:ui/hooks.dart:262:31)
(elided 3 frames from dart:async)

The AnimationController notifying status listeners was:
  AnimationController#cdfbd(▶ 0.000)
═════════════════════════════════════════════════════════════════

问题原因及解决

先说问题出现的原因和解决,错误提示这是Flutter中涉及到AnimationControllerScrollbar的一个异常。通常情况下,Scrollbar需要一个与之关联的ScrollPosition来进行绘制,但在这个情况下,没有找到ScrollControllerScrollPosition

解决方法:
方法一:手动添加一个ScrollController,使SingleChildScrollView可以得到正确的ScrollController。如果SingleChildScrollView.scrollDirection设置为垂直方向(Axis.vertical)且没有显式提供 ScrollController,那么它会去寻找PrimaryScrollController

方法二:如果想显式地使用 PrimaryScrollController,设置SingleChildScrollView.primarytrue

这里,我用了最简单的法子,在SingleChildScrollView组件中,设置primarytrue。即:

class _ScrollTest extends StatelessWidget{
  
  
  Widget build(BuildContext context){
    String str = "asdafdsfsdgee";
    return Scrollbar(
      interactive: true,
      child: SingleChildScrollView(
        primary: true, //新增加的
        padding: const EdgeInsets.all(16.0),
        child: Center(
          child: Column(
            children: str.split("").map((e) => Text(e,)).toList(),
          ),
        ),
      ),
    );
  }
}

相关补充

最后,补充一点SingleChildScrollView的相关内容,它类似于Android中的ScrollView,只能接收一个子组件,定义如下:

SingleChildScrollView({
  this.scrollDirection = Axis.vertical, //滚动方向,默认是垂直方向this.reverse = false, 
  this.padding,  
  bool primary, 
  this.physics, 
  this.controller,
  this.child,
})

其中,primary属性表示是否使用widget树中默认的PrimaryScrollControllerMaterialApp 组件树中已经默认包含一个PrimaryScrollController了);当滑动方向为垂直方向(scrollDirection值为Axis.vertical)并且没有指定controller时,primary默认为true
而通常SingleChildScrollView应在期望的内容不会超过屏幕太多时使用,这是因为SingleChildScrollView不支持基于Sliver的延迟加载模型,所以如果预计Viewport可能包含超出屏幕尺寸太多的内容时,那么使用SingleChildScrollView将会使性能变差,此时可以换成支持Sliver延迟加载的可滚动组件,如ListView

注:其中涉及到的Sliver、Viewport等概念是来自Flutter的两种布局模型。

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值