suma
suma

Reputation: 121

How to skip a page while swiping while using flutter PageView

I have a weekview with daily exercises logged like shown in the attachment. The days in red are disabled. When I swipe the page, it needs to skip the disabled tab and go directly to the next active tab. For e.g. if I'm on Sunday and swipe, it should go to Tuesday skipping monday and vice versa(if I swipe backwards from tuesday, it should go to monday). Also, clicking on enabled days should take me to the respective page.

Inside the pageview.builder I built the pages. When I swipe a page, itemBuilder of PageView is called and the pages changes based on the index and the index increments automatically. I'm not sure how to skip the disabled screens. Please help.

Here is my code:

Stack(
          children: <Widget>[
            new PageView.builder(
              controller: _controller,
              itemBuilder: (BuildContext context, int index) {
              return   Container(
                padding: EdgeInsets.only(top:50.0),
                child: ListView(
              children: <Widget>[
               Text('Trying out')
              ],
            ));
              },
            ),
            new Positioned(
              top: 0.0,
              left: 0.0,
              right: 0.0,
              child: Center(
                  child: new DotsIndicator(
                    controller: _controller,
                    itemCount: 7,
                    onPageSelected: (int page) {
                      _controller.animateToPage(
                        page,
                        duration: _kDuration,
                        curve: _kCurve,
                      );
                    },
                  ),
                ),)
                         )]
            )

Upvotes: 1

Views: 2397

Answers (1)

Manuel
Manuel

Reputation: 382

Here is a possible solution where the pages are sill there, but it automatically swipes over them. (To show the disabled, the page title gets set to grey).

I used a page controller and the onPageChanged property. This property is always called, after a fully executed page swipe. With the Method .nextPage & .previousPage it then automatically swipes over the page, depending on the swipe direction and whether the page is disabled or not (defined in the List disabledPages)

To differentiate between the swipe direction the last viewed page index is stored in variable previousPageViewIndex

class PageViewDemo extends StatefulWidget {
  @override
  _PageViewDemoState createState() => _PageViewDemoState();
}

class _PageViewDemoState extends State<PageViewDemo> {
  int _index = 0;

  List<Color> myColors = [
    Colors.blue,
    Colors.greenAccent,
    Colors.green,
    Colors.grey,
    Colors.deepPurpleAccent,
    Colors.deepOrangeAccent,
    Colors.pink,
    Colors.amber,
    Colors.cyanAccent,
    Colors.teal
  ];

  PageController pageController = PageController();
  int previousPageViewIndex = 0;

  // here are the current pages which should be disabled
  List<int> disabledPages = [2, 6, 7];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView.builder(
        onPageChanged: (index) {
          if(disabledPages.contains(index)) {           // check if current page is disabled
            if(index > previousPageViewIndex) {         // swipe right
              pageController.nextPage(duration: Duration(milliseconds: 800), curve: Curves.ease);
            } else if(index < previousPageViewIndex) {  // swipe left
              pageController.previousPage(duration: Duration(milliseconds: 800), curve: Curves.ease);
            }
          }
          previousPageViewIndex = index;
        },
        controller: pageController,
        itemBuilder: (context, index) {
          return Container(
            color: myColors[index],
            alignment: Alignment.center,
            child: Text('Page $index', style: TextStyle(fontSize: 28, color: disabledPages.contains(index) ? Colors.grey[500] : null)),
          );
        },
        itemCount: 10,
      ),
    );
  }
}

To get to a specific page on initialization use the .initPage property in the PageController.

Upvotes: 1

Related Questions