Как закрыть SearchDelegate с устаревшим контекстом? - PullRequest
0 голосов
/ 17 сентября 2018

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

Для этого поведения я использую обратные вызовы в моем виджете списка предложений без сохранения состояния, но в случае обратного вызова onMapTappedприложение выдает исключение:

class LocationSearchDelegate extends SearchDelegate<Location> {
  // ...
  @override
  Widget buildSuggestions(BuildContext context) {
    return _SuggestionList(
      query: query,
      onSelected: (Location suggestion) {
        result = suggestion;
        close(context, result);
      },
      onMapTapped: (Location location) {
        result = location;
        close(context, result); // <- Throws exception
      },
    );
  }
  // ...
}

Исключение:

Looking up a deactivated widget's ancestor is unsafe.
At this point the state of the widget's element tree is no longer stable. To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling inheritFromWidgetOfExactType() in the widget's didChangeDependencies() method.

Контекст метода buildSuggestions тем временем становится устаревшим из-за перехода к ChooseOnMapPage:

class _SuggestionList extends StatelessWidget {
  // ...
  void _handleOnChooseOnMapTap(BuildContext context) async {
    Location location = await Navigator.of(context).push(
      MaterialPageRoute<Location>(builder: (context) {
        return ChooseLocationPage();
      }),
    );
    onMapTapped(location);
  }
  // ...
}

Обходной путь

Текущий обходной путь - показать результаты, а затем немедленно закрыть делегат поиска:

class LocationSearchDelegate extends SearchDelegate<Location> {
  // ...
  @override
  Widget buildSuggestions(BuildContext context) {
    return _SuggestionList(
      query: query,
      onSelected: (Location suggestion) {
        result = suggestion;
        close(context, result);
      },
      onMapTapped: (Location location) {
        result = location;
        showResults(context); // <- Throws NO exception
      },
    );
  }
  // ...
  @override
  Widget buildResults(BuildContext context) {
    Future.delayed(Duration.zero, () {
      close(context, result);
    });
    return Container();
  }
  // ...
}

НадеюсьНе нравится этот обходной путь, так что какие-либо предложения о том, как это исправить?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...