Search code examples
flutterflutter-layoutflutter-pageview

Flutter: how to disable the scroll to the left in pageview?


and today when I am developing my app, I just find out that I need a feature that can only allow user to scroll to the right page, but not the left page, and the PageController does not provide any functionality that can allow me to implement that, so that's the reason why I am here!

I also visited this link:

StackOverflow: Custom ScrollPhysics, but it does not contain any explanation, you know it's painful to use other people's code without knowing what it is doing, right? So please help me!!! ^_^


Solution

  • You can create your own ScrollPhysics to lock the scroll to a direction, or you can use the horizontal_blocked_scroll_physics lib to help you.

    Here is an example of a CustomScrollPhysic that enable only right scrolling

    class CustomScrollPhysics extends ScrollPhysics {
      CustomScrollPhysics({ScrollPhysics parent}) : super(parent: parent);
    
      bool isGoingLeft = false;
    
      @override
      CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
        return CustomScrollPhysics(parent: buildParent(ancestor));
      }
    
      @override
      double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
        isGoingLeft = offset.sign < 0;
        return offset;
      }
    
      @override
      double applyBoundaryConditions(ScrollMetrics position, double value) {
        assert(() {
          if (value == position.pixels) {
            throw FlutterError(
              '$runtimeType.applyBoundaryConditions() was called redundantly.\n'
              'The proposed new position, $value, is exactly equal to the current position of the '
              'given ${position.runtimeType}, ${position.pixels}.\n'
              'The applyBoundaryConditions method should only be called when the value is '
              'going to actually change the pixels, otherwise it is redundant.\n'
              'The physics object in question was:\n'
              '  $this\n'
              'The position object in question was:\n'
              '  $position\n');
          }
          return true;
        }());
        if (value < position.pixels && position.pixels <= position.minScrollExtent)
          return value - position.pixels;
        if (position.maxScrollExtent <= position.pixels && position.pixels < value)
          return value - position.pixels;
        if (value < position.minScrollExtent &&
            position.minScrollExtent < position.pixels)
    
          return value - position.minScrollExtent;
    
        if (position.pixels < position.maxScrollExtent &&
            position.maxScrollExtent < value)
          return value - position.maxScrollExtent;
    
        if (!isGoingLeft) {
          return value - position.pixels;
        }
        return 0.0;
      }
    }
    

    You can use as the example below, CustomScrollPhysics as value to physics parameter.

    PageView.builder(
      physics: CustomScrollPhysics(),
    );
    

    Some references that could explain better how ScrollPhysics works