使用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. (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的两种布局模型。

你可能感兴趣的:(flutter,flutter,javascript,开发语言)