我有一个Flutter页面/小部件,带有一个搜索框和一个从flutter_bloc BLOC填充的ListView。
输入文本后,我调用BLOC方法搜索结果,结果显示在ListView中。
当我单击PopupMenuItem
项内的ListTile
时,我得到:
如果我用stations
变量的简单静态列表初始化替换BLOC“dance”,它就可以正常工作。
我完全不知道该怎么办?
有人可以给我一些指示吗?
编辑:
这是一个repro示例(仅适用于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
和访问context
的Scaffold
来解决此问题。不幸的是,这是不可能的。
但是,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/