Flutter - 如何覆盖滚动物理

scr*_*mau 5 listview scroll flutter

如何真正覆盖颤动 ListView 的滚动物理?

在我的具体用例中,我想重写 ListWheelScrollView 的滚动物理特性,以便仅以最大速度模拟释放平移后的模拟滚动,并且禁用“太快”的快速滑动。

到目前为止我尝试过的:

我创建了一个自定义滚动物理类:

class CustomScrollPhysics extends FixedExtentScrollPhysics {
  @override
  double get minFlingVelocity => double.infinity;

  @override
  double get maxFlingVelocity => double.infinity;

  @override
  double get minFlingDistance => double.infinity;

  @override
  SpringDescription get spring => SpringDescription.withDampingRatio(ratio: 0.7);

}
Run Code Online (Sandbox Code Playgroud)

我的理由是通过将抛掷速度和距离设置为无穷大并使用欠阻尼弹簧来减慢弹道滚动动画来禁用抛掷。

像这样使用它:

ListWheelScrollView.useDelegate(
              physics: CustomScrollPhysics(),
              clipToSize: true,
              useMagnifier: false,
              controller: scrollController,
              itemExtent: widget.itemExtent,
              childDelegate: ListWheelChildBuilderDelegate(
                builder: (context, toBuild) =>
                    toBuild < widget.min || toBuild > widget.max
                        ? null
                        : buildNumberWidget(context, toBuild),
              ),
            ),
Run Code Online (Sandbox Code Playgroud)

这绝对没有完成任何事情,然后我发现了这个,所以我添加了:

class CustomScrollPhysics extends FixedExtentScrollPhysics {
  //....
  @override
  FixedExtentScrollPhysics applyTo(ScrollPhysics ancestor) {
    return CustomScrollPhysics();
  }
}
Run Code Online (Sandbox Code Playgroud)

这完成了一些事情,但破坏了列表视图,特别是它现在在末尾溢出,并且在拖动后抛出异常:

 Another exception was thrown: 'package:flutter/src/widgets/scrollable.dart': Failed assertion: line 480 pos 12: '_drag == null': is not true.
Run Code Online (Sandbox Code Playgroud)

这种行为也独立于其他变化,他们仍然不会做任何事情。所以这显然与滚动物理的组合方式有关,所以我尝试使用FixedExtentScrollPhysics和ScrollPhysics的applyTo方法,但仍然没有运气。我想知道,如何在颤动中实际覆盖列表视图的滚动物理?是否应该实现一个子类?我是否必须以不同的方式使用 applyTo 方法?是否没有简单的方法来覆盖 spring/fling 行为并且我几乎坚持给定的类?

scr*_*mau 8

所以,我找到了一个可行的解决方案。

看起来自定义滚动物理机制必须覆盖它的构造和应用方式,以便在ListViews 中使用,例如ListWheelScrollView. 为此,必须实现一个带有parent参数的构造函数并调用super(parent:parent)ScrollPhysics类。然后,必须重写该applyTo方法以返回自定义滚动物理类的实例,并将ancestor参数包装buildParent(ancestor)parent构造函数的参数。然后它就会得到实际的正确应用。FixedExtentScrollPhysics因此,禁用投掷功能的示例是:

class CustomScrollPhysics extends FixedExtentScrollPhysics {
  const CustomScrollPhysics({ScrollPhysics parent})
      : super(parent: parent);

  @override
  double get minFlingVelocity => double.infinity;

  @override
  double get maxFlingVelocity => double.infinity;

  @override
  double get minFlingDistance => double.infinity;

  @override
  CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
    return CustomScrollPhysics(parent: buildParent(ancestor));
  }
}
Run Code Online (Sandbox Code Playgroud)

由于这似乎是 every 的ScrollPosition实现方式,因此看起来这是执行此类操作的隐含方式。找不到任何关于此的文档,并且不知道这是否是“正确”的方式。