gpt4 book ai didi

flutter - 为什么我的 PopupMenuItem 上会出现 "Looking up a deactivated widget' 的祖先不安全”?

转载 作者:行者123 更新时间:2023-12-04 21:18:48 28 4
gpt4 key购买 nike

我有一个 Flutter 页面/小部件,带有一个搜索框和一个从 flutter_bloc 填充的 ListView集团。
当输入文本时,我调用一个 BLOC 方法来搜索结果,并将结果呈现在一个 ListView 中。
enter image description here
当我点击 PopupMenuItemListTile我得到的项目:

enter image description here

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 dependOnInheritedWidgetOfExactTpye() in the widget's didChangeDepencies() method.



如果我用 stations 的简单静态列表初始化替换 BLOC“舞蹈”变量,它工作正常。

我完全不知道该怎么办?
有人可以给我一些指点吗?

编辑 :
这是一个重现示例(仅限 Android):
https://github.com/MagnusJohansson/bloc_test
单击应用程序中的搜索图标,输入“test”作为搜索词。单击三点状菜单以触发错误(可能需要单击两次)。
如果不执行 sqlite 查询,而是返回一个静态列表(如文件/bloc/searchpresets/search_presets_bloc.dart 第 55 行中的注释所示),它工作正常。
class SearchPresetsPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => _SearchPresetsPageState();
}

final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey2 =
new GlobalKey<RefreshIndicatorState>();

final GlobalKey<ScaffoldState> scaffoldKey2 = new GlobalKey<ScaffoldState>();

final snackBar = SnackBar(
content: Text('Added as a favorite'),
action: SnackBarAction(
label: 'Undo',
onPressed: () {},
),
);

class _SearchPresetsPageState extends State<SearchPresetsPage> {
final TextEditingController _filter = new TextEditingController();
List<Station> stations = [];

_textInputSearch() {
if (_filter.text.length >= 2) {
BlocProvider.of<SearchPresetsBloc>(context)
.add(SearchPresets(_filter.text));
}
}

@override
void initState() {
_filter.addListener(_textInputSearch);
super.initState();
}

Widget buildInitialStationsInput(BuildContext context, String message) {
return Column(children: <Widget>[
Center(child: Text(message)),
]);
}

Widget buildLoading() {
return Center(
child: LinearProgressIndicator(
value: null,
),
);
}

Widget _buildListView() {
return RefreshIndicator(
key: _refreshIndicatorKey2,
child: Column(
children: <Widget>[
Container(
color: Colors.grey[300],
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
"${stations.length} Stations:",
),
),
),
Expanded(
child: ListView.builder(
itemCount: stations != null ? stations.length : 0,
itemBuilder: (context, index) {
return Card(
child: ListTile(
dense: true,
title: Text(stations[index].name),
leading: IconButton(
alignment: Alignment.center,
icon: Icon(Icons.play_arrow),
onPressed: () async {
},
),
trailing: PopupMenuButton(
onSelected: (value) async {
},
itemBuilder: (context) {
return [
PopupMenuItem(
value: 1,
child: Text("Add to favorites"),
),
];
},
),
),
);
},
),
),
],
),
onRefresh: () async {
BlocProvider.of<SearchPresetsBloc>(context)
.add(SearchPresets(_filter.text));
},
);
}

@override
Widget build(BuildContext context) {
return BlocListener<SearchPresetsBloc, SearchPresetsState>(
listener: (BuildContext context, SearchPresetsState state) {},
child: Scaffold(
key: scaffoldKey2,
appBar: AppBar(
actions: <Widget>[],
title: Container(
color: Colors.white,
child: TextField(
controller: _filter,
decoration: new InputDecoration(
filled: true,
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
_filter.clear();
setState(() {
stations = [];
BlocProvider.of<SearchPresetsBloc>(context)
.add(ClearSearch());
});
},
),
prefixIcon: new Icon(Icons.search),
hintText: 'Search...'),
),
),
),
body: BlocBuilder<SearchPresetsBloc, SearchPresetsState>(
builder: (BuildContext context, SearchPresetsState state) {
if (state is InitialSearchPresetsState) {
return buildInitialStationsInput(context,
"Search for stations in the search box above (at least 2 characters)");
}
if (state is SearchPresetsLoading) {
return buildLoading();
}
if (state is SearchPresetsLoaded) {
stations = state.stations;
return _buildListView();
}
if (state is SearchPresetsError) {
return buildInitialStationsInput(
context, state.exception.toString());
}
return Container();
}),
),
);
}
}

最佳答案

这是contexts的问题.它经常发生在 Dialogs ,以及 PopMenu行为有点类似于对话框,但使用对话框您可以传递 context你想用 GlobalKey 解决这个问题并访问 contextScaffold .不幸的是,在这里这是不可能的。

尽管如此,PopMenuButton 上有一个标志似乎可以解决您的问题。 captureInheritedThemes . documentation状态:“如果为 true(默认值),则菜单将包含 InheritedThemes 的副本,例如 Theme 和 PopupMenuTheme,,它们定义在 BuildContext 上方,其中显示菜单 ”。那似乎是我们的问题,上下文的继承。

在您的 search_presets_widget.dart 文件中,在您的 PopupMenuButton 中内_buildListView方法,添加这一行:

PopupMenuButton(
captureInheritedThemes: false, // Add this line
...

关于flutter - 为什么我的 PopupMenuItem 上会出现 "Looking up a deactivated widget' 的祖先不安全”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59636507/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com