Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter - PageView animatedToPage will load middle page. How to avoid it?

Tags:

flutter

I have a PageView, I want scroll pageView programmatically, so I have two choices:

  1. use animateToPage
  2. use jumpToPage

now, I need smooth transition effect, so I have to use first api. But, I have a problem: animateToPage will load middle pages which don't need to be shown at this time when I scroll from the first page to the last page.(jumpToPage don't have this problem, but I need animation).

How to avoid it?

like image 354
Leo.J Avatar asked Aug 21 '19 07:08

Leo.J


People also ask

How do you implement pageviews in flutter?

Scroll down to the end to get the full code demo. A PageView widget allows the user to swipe/transition between different screens in your app. All you need to set it up are a PageViewController and a PageView. You can use PageController to control which page is visible in the view.


1 Answers

We can achieve that by

  1. Swap lastPage Widget to next position of current page
  2. Animate to next page
  3. Jump to real lastPage index
  4. Refresh swapped Index to its previous value

In this example, I used fixed PageView children count, which is 8.

Demo

Demo

Comparison

  1. Combine to 8th page Button

as CopsOnRoad suggested, this button will trigger Scroll animation to last page (in this case 8th page). Firstly, we jumpToPage(6), and then animateToPage(7, ..).

This method works, but adversely, user will notice sudden change of current page to 7th page.

  1. Flash Jump to 8th page Button

Unlike like first method, this button will avoid displaying 7th page unnecessarily

Syntax Explanation

this is the main function

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
}

detailed look

// 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();
  });
}

Full Working-Example Repository

You may look into full source code and build locally. Github

like image 200
ejabu Avatar answered Sep 22 '22 07:09

ejabu