Пользовательская физика прокрутки для прогрессирования PageView во флаттере - PullRequest
0 голосов
/ 07 октября 2019

Я хотел бы создать прогрессию PageView с пользовательским ScrollPhysics, чтобы пользователь мог прокручивать только до готовых вкладок. Для справки см. Следующее изображение, справа вверху показана последовательность (зеленый = доступные, красные = недоступные страницы):

1]

На снимке экрана я завершил страницы 1 и 2, и я надеваюне хочу, чтобы пользователь пролистал до страницы 3, что происходит прямо сейчас. Я прочитал примеры в scroll_physics.dart для реализаций iOS и Android. Но я все еще застрял.

Я попробовал это здесь , но оно прослушивается. Вы можете предотвратить переход пользователя вправо, но если последняя доступная страница не полностью видна, как на скриншоте, прокрутка уже заблокирована, и вы не можете прокрутить вправо.

Вот мой код справасейчас:

Вызывается с:

PageView(
          controller: PageController(
            initialPage: model.initallPage,
          ),
          children: pages,
          physics: model.currentPage >= model.lastAccessiblePage ? CustomScrollPhysics(CustomScrollStatus()..rightEnd = true) : ScrollPhysics(),
          onPageChanged: (value) {
            model.currentPage = value;
          },
        ),

Настраиваемая физика прокрутки:

class CustomScrollStatus {
  bool leftEnd = false;
  bool rightEnd = false;
  bool isGoingLeft = false;
  bool isGoingRight = false;
}

class CustomScrollPhysics extends ScrollPhysics {
  final CustomScrollStatus status;

  CustomScrollPhysics(
    this.status, {
    ScrollPhysics parent,
  }) : super(parent: parent);

  @override
  CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
    return CustomScrollPhysics(this.status, parent: buildParent(ancestor));
  }

  @override
  double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
    status.isGoingLeft = offset.sign < 0;
    return offset;
  }

  @override
  double applyBoundaryConditions(ScrollMetrics position, double value) {
    if (value < position.pixels && position.pixels <= position.minScrollExtent) {
      print('underscroll');
      return value - position.pixels;
    }
    if (position.maxScrollExtent <= position.pixels && position.pixels < value) {
      print('overscroll');
      return value - position.pixels;
    }
    if (value < position.minScrollExtent && position.minScrollExtent < position.pixels) {
      print('hit top edge');
      return value - position.minScrollExtent;
    }
    if (position.pixels < position.maxScrollExtent && position.maxScrollExtent < value) {
      print('hit bottom edge');
      return value - position.maxScrollExtent;
    }

    if (status.leftEnd) print("leftEnd");
    if (status.rightEnd) print("rightEnd");
    if (status.isGoingLeft) print("isGoingLeft");
    if (status.isGoingRight) print("isGoingRight");

    // do something to block movement > accesssible page

    print('default');
    return 0.0;
  }
}

Редактировать:

Я подумал о совершенно другом решении. Динамическое изменение дочерних элементов PageView. Я все еще заинтересован в переопределении решения ScrollPhysics, так как оно, на мой взгляд, чище.

children: pages

...