Flutter中滑动出现_positions.isNotEmpty异常解决办法

3,738 阅读1分钟

昨天从其他页面回到首页,滑动banner图切换时发现一个错误,虽然没有导致崩溃,但是总是觉得不舒服:

Unhandled Exception: 'package:flutter/src/widgets/scroll_controller.dart': 
Failed assertion: line 110 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.
#0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:42:39)
#1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:38:5)
#2      ScrollController.position 

由于bannerView是通过pageView组件来实现的,在触发PageController的animateToPage方法发生的这个错误,我尝试着将animateToPage方法替换成jumpTo方法,还是回出现这个错误,说明这应该是PageController对象出现错误导致的,继续查看源码发现,PageController是继承自ScrollController控制器的,然后我在scroll_controller文件全局搜索 '_positions.isNotEmpty'找到来这个错误的根源,

 Future<void> animateTo(
    double offset, {
    @required Duration duration,
    @required Curve curve,
  }) {
    assert(_positions.isNotEmpty, 'ScrollController not attached to any scroll views.');
    final List<Future<void>> animations = List<Future<void>>(_positions.length);
    for (int i = 0; i < _positions.length; i += 1)
      animations[i] = _positions[i].animateTo(offset, duration: duration, curve: curve);
    return Future.wait<void>(animations).then<void>((List<void> _) => null);
  }

通过源码发现,animateTo方法中有一个断言,如果_positions.isNotEmpty,就回抛出这个错误,继续搜索_positions.isNotEmpty发现指向来一个变量hasClients,很明显只要在执行animateTo方法前判断一下hsaClients方法就可以了,

        if(_pageController.hasClients) {
          _pageController.animateToPage(
            _curIndex,
            duration: Duration(milliseconds: 300),
            curve: Curves.linear,
          );
        }

只需要在_pageController.hasClients为true的情况下,也就是说_pageController已经依附于pageView的情况下,才能够调用animateToPage方法,这里要注意的是,除了animateToPage方法,当调用position,position,jumpTo等方法都回存在这个问题,特别是第二次中心构建页面的时候需要注意。