Flutter 擴展NestedScrollView (三)下拉刷新的解決

Extended NestedscrollView 相關文章html

如今推薦你們食用Flutter 下拉刷新花式玩法,支持各類下拉刷新姿式,更多姿式等你來解鎖。git

解決點以前的2個問題。開心的上項目試了下。完美。github

FlutterCandies QQ羣:181398081 bash

pub package

可是在使用官方的下拉刷新 RefreshIndicator 發現無法使用。svg

默默打開了源碼,咱們再來看一看。。post

首先,我調試到這個,發現notification.depth不爲0,其實也好理解,由於NestedScrollView裏面有不少能滾動的東西。默認的RefreshIndicator要求的是必須是第一層的它才其效果。ui

/// A [ScrollNotificationPredicate] that checks whether
/// `notification.depth == 0`, which means that the notification did not bubble
/// through any intervening scrolling widgets.
bool defaultScrollNotificationPredicate(ScrollNotification notification) {
  return notification.depth == 0;
}
複製代碼

那麼我改爲,再試試呢?this

bool defaultScrollNotificationPredicate(ScrollNotification notification) {
  return true;
  return notification.depth == 0;
}
複製代碼

在_handleScrollNotification方法中,咱們能夠看到會有不少ScrollNotification進來,不一樣的,當你滑動在一個不能滾動的list裏面的時候,獲取的viewportDimension是爲0.。這會覆蓋掉以前有viewportDimension的值。spa

因此我作了如下改動調試

double maxContainerExtent = 0.0;
  bool _handleScrollNotification(ScrollNotification notification) {
    if (!widget.notificationPredicate(notification)) return false;
    maxContainerExtent = math.max(
        notification.metrics.viewportDimension, this.maxContainerExtent);
    if (notification is ScrollStartNotification &&
        notification.metrics.extentBefore == 0.0 &&
        _mode == null &&
        _start(notification.metrics.axisDirection)) {
      setState(() {
        _mode = _RefreshIndicatorMode.drag;
      });
      return false;
    }
    bool indicatorAtTopNow;
    switch (notification.metrics.axisDirection) {
      case AxisDirection.down:
        indicatorAtTopNow = true;
        break;
      case AxisDirection.up:
        indicatorAtTopNow = false;
        break;
      case AxisDirection.left:
      case AxisDirection.right:
        indicatorAtTopNow = null;
        break;
    }
    if (indicatorAtTopNow != _isIndicatorAtTop) {
      if (_mode == _RefreshIndicatorMode.drag ||
          _mode == _RefreshIndicatorMode.armed)
        _dismiss(_RefreshIndicatorMode.canceled);
    } else if (notification is ScrollUpdateNotification) {
      if (_mode == _RefreshIndicatorMode.drag ||
          _mode == _RefreshIndicatorMode.armed) {
        if (notification.metrics.extentBefore > 0.0) {
          _dismiss(_RefreshIndicatorMode.canceled);
        } else {
          _dragOffset -= notification.scrollDelta;
          _checkDragOffset(maxContainerExtent);
        }
      }
      if (_mode == _RefreshIndicatorMode.armed &&
          notification.dragDetails == null) {
        // On iOS start the refresh when the Scrollable bounces back from the
        // overscroll (ScrollNotification indicating this don't have dragDetails
        // because the scroll activity is not directly triggered by a drag).
        _show();
      }
    } else if (notification is OverscrollNotification) {
      if (_mode == _RefreshIndicatorMode.drag ||
          _mode == _RefreshIndicatorMode.armed) {
        _dragOffset -= notification.overscroll / 2.0;
        _checkDragOffset(maxContainerExtent);
      }
    } else if (notification is ScrollEndNotification) {
      switch (_mode) {
        case _RefreshIndicatorMode.armed:
          _show();
          break;
        case _RefreshIndicatorMode.drag:
          _dismiss(_RefreshIndicatorMode.canceled);
          break;
        default:
          // do nothing
          break;
      }
    }
    return false;
  }
複製代碼

對於NestedScrollView 來講。咱們只須要關注最大能滾動viewportDimension,用這個來驅動整個下拉刷新.

Sample Code

用法跟官方一致

return NestedScrollViewRefreshIndicator(
      onRefresh: onRefresh,
      child: extended.NestedScrollView(
複製代碼

最後放上 Github extended_nested_scroll_view,若是你有更好的方式解決這個問題或者有什麼不明白的地方,都請告訴我,由衷感謝。

pub package

相關文章
相關標籤/搜索