有两个下拉按钮,显示国家和运动类型的列表。如果在他们身上选择了Somsetting,则需要显示列表。国家和/或体育选择了带有联赛的Tile,如果在他们上面什么都没有选择,则显示所有联赛。
但我得到了:
Dart错误:未处理的异常:dispose()后调用的setState():_SportLigPageState#b5830(生命周期状态:已失效,未装入)如果您看到小部件树(例如),就会发生这种情况。在进行调用时可能会发生此错误。Dispose()回调。有必要确保对象仍在树中。如果不是的话,这可能是一张存储卡。为了避免内存泄漏,请考虑dispose()。
Api与联赛:https://www.thesportsdb.com/api/v1/json/1/all_leagues.php:
class LigList extends StatefulWidget {
@override
_LigListState createState() => _LigListState();
}
class _LigListState extends State<LigList> {
String sport;
String country;
List data;
Future<String> getJsonData() async {
http.Response response;
if (sport != null) {
if (country != null) response = await http
.get(Uri.encodeFull('https://www.thesportsdb.com/api/v1/json/1/all_leagues.php?c=$sport&s=$country'), headers: {"Accept": "application/json"});
else response = await http
.get(Uri.encodeFull('https://www.thesportsdb.com/api/v1/json/1/all_leagues.php?c=$sport'), headers: {"Accept": "application/json"});}
else if (country == null){ response = await http
.get(Uri.encodeFull('https://www.thesportsdb.com/api/v1/json/1/all_leagues.php'), headers: {"Accept": "application/json"});}
else response = await http
.get(Uri.encodeFull('https://www.thesportsdb.com/api/v1/json/1/all_leagues.php?c=$country'), headers: {"Accept": "application/json"});
var convertDatatoJson = json.decode(response.body);
data = convertDatatoJson['leagues'];
return "Success";
}
static const menuItems = countriesList;
final List<DropdownMenuItem<String>> _dropDownItems = menuItems
.map((String CountruValue) =>
DropdownMenuItem<String>(
value: CountruValue,
child: Text(CountruValue),
),
).toList();
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Column(children: <Widget>[
FutureBuilder(
builder: (BuildContext context, AsyncSnapshot snapshot) {
return DropdownButton(
value: country,
hint: Text("Choose a countre league of which you want to find"),
items: _dropDownItems,
onChanged: (value) {
country = value;
print(country);
setState(() {});
},
);}),
SizedBox(width: 5),
FutureBuilder(
future: _getSports(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return snapshot.hasData
? DropdownButton(
value: sport,
hint: Text("Choose a sport league of which you want to find"),
items: snapshot.data,
onChanged: (value) {
sport = value;
print(sport);
setState(() {});
},
)
: Padding(
padding: EdgeInsets.symmetric(vertical: 20),
child: CircularProgressIndicator());
}),
Flexible(
child:FutureBuilder(
future: getJsonData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return ListView.separated(
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext context, int i) {
return Container(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment
.stretch,
children: <Widget>[
ListTile(
title: Text(data[i]['strLeague']),
subtitle: Text(
data[i]['strSport']),
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (
BuildContext context) =>
new ComandListScreen()
// (data[i])
));
},
),
]
)
)
);
});
}))
]),
),
);
}
}
我们非常感谢任何协助。
您的代码有很多错误。代码中的第一个子级被封装在FutureBuilder中,但您没有使用任何Future功能。
FutureBuilder(
builder: (BuildContext context, AsyncSnapshot snapshot) {
return DropdownButton(
value: country,
hint: Text("Choose a countre league of which you want to find"),
items: _dropDownItems,
onChanged: (value) {
country = value;
print(country);
setState(() {}); // Remove this line
},
);}),
除此之外,你还在onChanged回调中随机调用setState(),里面什么都没有。我建议你从FutureBuilder中取出这个小部件,只需自己使用DropdownButton。
然后也在这条线上
itemCount: data == null ? 0 : data.length,
您正在使用数据,这些数据是在未来设置的,您称之为数据。您可能想了解如何正确使用FutureBuilder小部件。只需从_getJsonData()Future返回数据对象,因为它总是返回"成功"。从Future返回您想要的列表,然后使用snapshot.data 访问它
最后,实际上只有一个setState调用,所以删除它,你就没事了。我的假设是,你打电话或导航离开时会有一些额外的处理,应用程序会崩溃。需要更多的信息才能弄清楚,但你必须修复你使用Futures和Future生成器的方式,这样我们才能确保这不是因为潜在的线程会回来,并在你离开视图后设置状态。