欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android Flutter實(shí)現(xiàn)上拉加載組件的示例代碼

 更新時(shí)間:2022年08月29日 09:34:24   作者:JulyYu  
既然列表有下拉刷新外當(dāng)然還有上拉加載更多操作了,本次就為大家詳細(xì)介紹如何利用Flutter實(shí)現(xiàn)為列表增加上拉加載更多的交互,感興趣的可以了解一下

前言

在此之前對(duì)列表下拉刷新做了調(diào)整方案,具體介紹可以閱讀下拉刷新組件交互調(diào)整。既然列表有下拉刷新外當(dāng)然還有上拉加載更多操作了,本次就來介紹如何為列表增加上拉加載更多的交互實(shí)現(xiàn)。

實(shí)現(xiàn)方案

上拉刷新實(shí)現(xiàn)形式上可以有多種實(shí)現(xiàn)方式,若不帶交互形式可采用NotificationListener組件監(jiān)聽滑動(dòng)來實(shí)現(xiàn)上拉加載更多;如果對(duì)操作交互上有一定要求期望上拉刷新帶有直觀動(dòng)畫可操作性就需要實(shí)現(xiàn)一定樣式來實(shí)現(xiàn)了。

監(jiān)聽NotificationListener實(shí)現(xiàn)

NotificationListener(
      onNotification: (scrollNotification) {
        if (scrollNotification.metrics.pixels >=
                scrollNotification.metrics.maxScrollExtent - size.height &&
            scrollNotification.depth == 0) {
          if (!isLoading) {
            isLoading = true;
            Future.delayed(Duration(seconds: 1), () {
              isLoading = false;
              length += 10;
              Scaffold.of(context).showSnackBar(SnackBar(
                content: Text('下拉加載更多了!?。?),
                duration: Duration(milliseconds: 700),
              ));
              setState(() {});
            });
          }
        }
        return false;
      }
  ......
  )

NotificationListener增加樣式

     SliverToBoxAdapter(
       child: Center(
         child: Text(
           length < 30 ? "加載更多...." : "沒有更多",
           style: TextStyle(fontSize: 25),
         ),
       ),
     )

ScrollPhysics調(diào)整

BouncingScrollPhysicsiOS帶有阻尼效果滑動(dòng)交互,在下拉刷新中帶有回彈阻尼效果是比較好的交互,但在上拉加載更多獲取交互上這種效果或許有點(diǎn)多余。因此需要定制下拉刷新帶有回彈阻尼效果,上拉加載沒有回彈阻尼效果的。ScrollPhysics

CustomScrollView(
   physics: BouncingScrollPhysics(),
   slivers: <Widget>[]
)

具體實(shí)現(xiàn)代碼如下所示:

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

  @override
  CustomBouncingScrollPhysics applyTo(ScrollPhysics ancestor) {
    return CustomBouncingScrollPhysics(parent: buildParent(ancestor));
  }

  double frictionFactor(double overscrollFraction) => 0.52 * math.pow(1 - overscrollFraction, 2);



  /// 阻尼參數(shù)計(jì)算
  @override
  double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
    assert(offset != 0.0);
    assert(position.minScrollExtent <= position.maxScrollExtent);

    if (!position.outOfRange)
      return offset;

    final double overscrollPastStart = math.max(position.minScrollExtent - position.pixels, 0.0);
    final double overscrollPastEnd = math.max(position.pixels - position.maxScrollExtent, 0.0);
    final double overscrollPast = math.max(overscrollPastStart, overscrollPastEnd);
    final bool easing = (overscrollPastStart > 0.0 && offset < 0.0)
        || (overscrollPastEnd > 0.0 && offset > 0.0);
    final double friction = easing
    // Apply less resistance when easing the overscroll vs tensioning.
        ? frictionFactor((overscrollPast - offset.abs()) / position.viewportDimension)
        : frictionFactor(overscrollPast / position.viewportDimension);
    final double direction = offset.sign;

    return direction * _applyFriction(overscrollPast, offset.abs(), friction);
  }

  static double _applyFriction(double extentOutside, double absDelta, double gamma) {
    assert(absDelta > 0);
    double total = 0.0;
    if (extentOutside > 0) {
      final double deltaToLimit = extentOutside / gamma;
      if (absDelta < deltaToLimit)
        return absDelta * gamma;
      total += extentOutside;
      absDelta -= deltaToLimit;
    }
    return total + absDelta;
  }


  /// 邊界條件 復(fù)用ClampingScrollPhysics的方法 保留列表在底部的邊界判斷條件
  @override
  double applyBoundaryConditions(ScrollMetrics position, double value){
    if (position.maxScrollExtent <= position.pixels && position.pixels < value) // overscroll
      return value - position.pixels;
    if (position.pixels < position.maxScrollExtent && position.maxScrollExtent < value) // hit bottom edge
      return value - position.maxScrollExtent;
    return 0.0;
  }

  @override
  Simulation createBallisticSimulation(ScrollMetrics position, double velocity) {
    final Tolerance tolerance = this.tolerance;
    if (velocity.abs() >= tolerance.velocity || position.outOfRange) {
      return BouncingScrollSimulation(
        spring: spring,
        position: position.pixels,
        velocity: velocity * 0.91, // TODO(abarth): We should move this constant closer to the drag end.
        leadingExtent: position.minScrollExtent,
        trailingExtent: position.maxScrollExtent,
        tolerance: tolerance,
      );
    }
    return null;
  }

  @override
  double get minFlingVelocity => kMinFlingVelocity * 2.0;

  @override
  double carriedMomentum(double existingVelocity) {
    return existingVelocity.sign *
        math.min(0.000816 * math.pow(existingVelocity.abs(), 1.967).toDouble(), 40000.0);
  }

  @override
  double get dragStartDistanceMotionThreshold => 3.5;
}

但是直接會(huì)發(fā)生錯(cuò)誤日志,由于回調(diào)中OverscrollIndicatorNotification是沒有metrics對(duì)象。對(duì)于

The following NoSuchMethodError was thrown while notifying listeners for AnimationController:
Class 'OverscrollIndicatorNotification' has no instance getter 'metrics'.

由于上滑沒有阻尼滑動(dòng)到底部回調(diào)Notification發(fā)生了變化,因此需要在NotificationListener中增加判斷對(duì)超出滑動(dòng)范圍回調(diào)進(jìn)行過濾處理避免異常情況發(fā)生。

   if(scrollNotification is OverscrollIndicatorNotification){
     return false;
   }

結(jié)果展示

演示代碼看這里

以上就是Android Flutter實(shí)現(xiàn)上拉加載組件的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Android Flutter上拉加載的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論