Search code examples
flutterflutter-layout

Non-center alignment for PageView with viewportFraction < 1.0


When you create a PageView with a viewportFraction value of <1.0 for the PageController, the pages are snapped to the center of the viewport, like so:

enter image description here

I want the current pages to be snapped to the top of the viewport, while the next page is rendered under the bottom bar. I've tried applying a transform to each page:

Transform.translate(offset: Offset(0.0, -36.0), child: page)

This appears to work at first glance (see first image), but fails to render the next page when it would be hidden without the transform (see second image):

enter image description here enter image description here

I've thought of using a ListView with PageScrollPhysics (which does behave correctly), but then I lose the pagination APIs (the ability to see which page I'm on/jump to a page). What would be the appropriate way to do this, in a way that always renders the next page when it's on-screen?


Solution

  • I'm actually trying to achieve something similar, I did ask a question here: Is there a way to disable PageView clipping effect?

    But thanks to you, your thought of approaching with ListView & PageScrollPhysics is just brilliant, I can solve it now. For calculating the page, you just need to do this:

    ScrollController controller = ScrollController();
    controller.addListener((){
      int page = (controller.offset / viewportWidth).round();
    });
    // which "viewportWidth" is the width of your page item.
    

    or if you want to animate to a specific page, do this:

    int page = 3;
    controller.animateTo(
      page.toDouble() * viewportWidth,
      duration: Duration(milliseconds: 300),
      curve: Curves.ease,
    );