我已经为我的位置搜索代表构建了一个建议列表,该列表始终在顶部有一个将用户推送到新页面的项目。用户可以在这个新页面上选择地图上的位置并提交或返回搜索页面。如果用户提交了位置,则我要关闭基础位置搜索委托,并以所选位置作为结果。
为此,我在无状态建议列表窗口小部件中使用了回调,但是在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();
}
// ...
}
我不喜欢这种解决方法,因此,有关如何解决此问题的任何建议?