我有一个PageView,我想以编程方式滚动pageView,所以我有两个选择:

  • 使用animateToPage
  • 使用jumpToPage

  • 现在,我需要平滑的过渡效果,因此我必须使用第一个api。但是,我有一个问题:animateToPage将加​​载当我从首页滚动到最后一页时不需要显示的中间页面(jumpToPage没有这个问题,但是我需要动画)。

    如何避免呢?

    最佳答案

    我们可以通过实现

  • 将lastPage小部件交换到当前页面的下一个位置
  • 动画到下一页
  • 跳转到实际的lastPage索引
  • 刷新交换的索引为其先前的值


  • 在此示例中,我使用了固定的 PageView子级计数,即8。

    演示版

    Flutter-PageView animateToPage将加载中间页面。如何避免呢?-LMLPHP

    比较
  • 合并到第8页按钮

  • 如CopsOnRoad建议的那样,此按钮将触发滚动动画至最后一页(在本例中为第8页)。首先,我们
    jumpToPage(6),然后设置animateToPage(7,..)。

    这种方法可以使用,但不利的是,用户会注意到当前页面突然更改为第7页
  • Flash跳至第8页按钮

  • 与第一种方法不同,此按钮将避免不必要地显示第7页

    语法说明

    这是的主要功能

    void flashToEight() async {
      int pageCurrent = pageController.page.round();
      int pageTarget = 7;
      if (pageCurrent == pageTarget){
        return;
      }
      swapChildren(pageCurrent, pageTarget); // Step # 1
      await quickJump(pageCurrent, pageTarget); // Step # 2 and # 3
      WidgetsBinding.instance.addPostFrameCallback(refreshChildren); // Step # 4
    }
    

    详细外观

    // Step # 1
    void swapChildren(int pageCurrent, int pageTarget) {
      List<Widget> newVisiblePageViews = [];
      newVisiblePageViews.addAll(pageViews);
    
      if (pageTarget > pageCurrent) {
        newVisiblePageViews[pageCurrent + 1] = visiblePageViews[pageTarget];
      } else if (pageTarget < pageCurrent) {
        newVisiblePageViews[pageCurrent - 1] = visiblePageViews[pageTarget];
      }
    
      setState(() {
        visiblePageViews = newVisiblePageViews;
      });
    }
    
    // Step # 2 and # 3
    Future quickJump(int pageCurrent, int pageTarget) async {
      int quickJumpTarget;
    
      if (pageTarget > pageCurrent) {
        quickJumpTarget = pageCurrent + 1;
      } else if (pageTarget < pageCurrent) {
        quickJumpTarget = pageCurrent - 1;
      }
      await pageController.animateToPage(
        quickJumpTarget,
        curve: Curves.easeIn,
        duration: Duration(seconds: 1),
      );
      pageController.jumpToPage(pageTarget);
    }
    
    // Step # 4
    List<Widget> createPageContents() {
        return <Widget>[
          PageContent(1),
          PageContent(2),
          PageContent(3),
          PageContent(4),
          PageContent(5),
          PageContent(6),
          PageContent(7),
          PageContent(8),
        ];
      }
    
    void refreshChildren(Duration duration) {
      setState(() {
        visiblePageViews = createPageContents();
      });
    }
    

    完整的工作示例存储库

    您可以查看完整的源代码并在本地构建。 Github

    10-01 21:03