Событие, когда ScrollController присоединяется

Я пытаюсь отобразить виджет, когда у меня есть информация о максимальной степени прокрутки. Я могу найти этот номер, если я назначу экземпляр ScrollController к controller свойство прокручиваемого виджета.

Моя проблема в том, что ScrollController привязывается к прокручиваемому виджету во время сборки, поэтому я не могу использовать максимальный номер экстента прокрутки перед первой сборкой. Таким образом, то, что я пытался сделать, это отобразить пустой Container в первой сборке, а затем переключите эту пустую Container с виджетом, который я на самом деле хочу. Что-то вроде этого:

    _scrollController.positions.length == 0 ? new Container() : new Align(
      alignment: Alignment.center,
      child: new Container(
        width: constraints.maxWidth,
        height: 50.0,
        color: Colors.black,
      )
    )

Теперь это не работает, конечно, потому что _scrollController.positions.length будет 0 в начале и никуда я не позвоню setState когда это значение изменяется (когда контроллер подключается).
Итак, мой вопрос: есть ли место, где я могу получать уведомления, когда ScrollController привязывается к прокручиваемому виджету? Или есть лучший подход для этого?

1 ответ

Решение

Если прокручиваемый widget.child,

@override
Widget build(BuildContext context) {
  return new NotificationListener<ScrollNotification>(
    onNotification: _handleScrollNotification,
    child: widget.child,
  );
}

bool _handleScrollNotification(ScrollNotification notification) {
  if (notification is ScrollUpdateNotification || notification is OverscrollNotification) {
    widget.child.update(notification.metrics);
  }
return false;
}

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_) => afterFirstLayout(context));
}

void afterFirstLayout(BuildContext context) {
  applyInitialScrollPosition();
}

void applyInitialScrollPosition() {
  ScrollController scrollControler = widget.child.controller;
  ScrollPosition position = scrollControler.position;
  ScrollNotification notification = ScrollUpdateNotification(
      metrics: FixedScrollMetrics(
          minScrollExtent: position.minScrollExtent,
          maxScrollExtent: position.maxScrollExtent,
          pixels: position.pixels,
          viewportDimension: position.viewportDimension,
          axisDirection: position.axisDirection),
      context: null,
      scrollDelta: 0.0);
_handleScrollNotification(notification);
}

Ребенок должен extends ChangeNotifier и имеет update метод:

void update(ScrollMetrics metrics) {
  assert(metrics != null);
  _lastMetrics = metrics; // Save the metrics.
  notifyListeners();
}

Все это работает, только если контроллер прокрутки был явно определен для прокручиваемого объекта (widget.child).

Другие вопросы по тегам