Flutter:为用户滚动增加摩擦,而不是弹簧

the*_*het 14 listview scroll flutter

我有一个带有自定义滚动物理类的列表视图,它定义了我想要的列表的滚动和弹簧效果。我已经设法按照我想要的方式设置弹簧阻尼,但我似乎找不到任何设置来使用户的阻力变

我的意思是,当用户拖动时,我希望列表感觉它有张力,因此用户需要比平时拖动得更远,我将使用自定义滚动物理处理列表中下一个项目的移动.

我希望它感觉像在火车站的转弯风格。你的身体会承受很多压力,一旦你通过转弯,风格就会重置为中心。

列表:

child: ListView.builder(
  cacheExtent: MediaQuery.of(context).size.height * 2,
  padding: EdgeInsets.only(top: 0),
  itemExtent: constraints.maxHeight -
      SizeConfig.blockSizeVertical * 40,
  itemCount: channelList?.length ?? 0,
  controller: _controller,
  physics: _physics,
  itemBuilder: (BuildContext context, int index) =>
      buildList(index),
),
Run Code Online (Sandbox Code Playgroud)

自定义滚动类:

import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';

class CustomScrollPhysics extends ScrollPhysics {
  final double itemDimension;
  static final SpringDescription customSpring =
      SpringDescription.withDampingRatio(
    mass: 4,
    stiffness: 150.0,
    ratio: 2.0,
  );

  @override
  double get dragStartDistanceMotionThreshold => 40;

  @override
  double get minFlingVelocity => double.infinity;

  @override
  double get maxFlingVelocity => double.infinity;

  @override
  double get minFlingDistance => double.infinity;

  CustomScrollPhysics({this.itemDimension, ScrollPhysics parent})
      : super(parent: parent);

  @override
  CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
    return CustomScrollPhysics(
        itemDimension: itemDimension, parent: buildParent(ancestor));
  }

  double _getPage(ScrollPosition position) {
    return position.pixels / itemDimension;
  }

  double _getPixels(double page) {
    return page * itemDimension;
  }

  double _getTargetPixels(
      ScrollPosition position, Tolerance tolerance, double velocity) {
    double page = _getPage(position);
    if (velocity < -tolerance.velocity) {
      page -= 0.01;
    } else if (velocity > tolerance.velocity) {
      page += 0.01;
    }
    return _getPixels(page.roundToDouble());
  }

  @override
  Simulation createBallisticSimulation(
      ScrollMetrics position, double velocity) {
    // If we're out of range and not headed back in range, defer to the parent
    // ballistics, which should put us back in range at an item boundary.
    if ((velocity <= 0.0 && position.pixels <= position.minScrollExtent) ||
        (velocity >= 0.0 && position.pixels >= position.maxScrollExtent))
      return super.createBallisticSimulation(position, (velocity));
    final Tolerance tolerance = this.tolerance;
    final double target = _getTargetPixels(position, tolerance, velocity);
    if (target != position.pixels) {
      return ScrollSpringSimulation(
          customSpring, position.pixels, target, velocity,
          tolerance: tolerance);
    }
    return null;
  }

  @override
  bool get allowImplicitScrolling => false;
}

/// Note: This Widget creates the ballistics model for a snap-to physics in a ListView.
/// Normally you might use the ListViewScrollView, however that widget currently
/// has a bug that prevents onTap detection of child widgets.

Run Code Online (Sandbox Code Playgroud)

该列表以屏幕为中心,大约为视图高度的 60%。

Jan*_*sen 1

如果您一次只需要显示列表中的一项,并且一项的渲染适合屏幕,那么使用PageView小部件可能会给您带来您想要的效果。