我有这个:
List<Students> studentList= [];
Future<List<Students>> getJsonData() async {
final String response = await rootBundle.loadString('assets/students.json');
final data = await json.decode(response);
studentList= await data.map<Sudents>((json) => Sudents.fromJson(json)).toList();
return studentList;
}
class TestPage extends StatefulWidget {
const TestPage ({super.key});
@override
State<TestPage > createState() => TestPage State();
}
class TestPage State extends State<TestPage > {
@override
Widget build(BuildContext context) {
return Scaffold(
AppBar:...
bottomNavigationBar:...
body:FutureBuilder<List<Students>>(
future: getJsonData() ,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const Center(child: Text("waiting"),);
default:
if(snapshot.hasError == false){
return BuildPage();
}
}
)
)
}
在 BuildaPage 内我有一个下拉列表。 当我在此下拉列表中选择一个元素时,我会调用 setState() 进行更新。 我需要调用 setState 因为当我选择一项时我需要设置一个 Contorller 的文本字段。
所以问题就在这里。首先,我收到一个红页错误,指出此下拉列表中的 或 为空或重复的项目...
“应该只有一项具有 [DropdownButton] 的值:“模型”实例。 检测到零个或 2 个或更多 [DropdownMenuItem] 具有相同的值”
第二步是再次调用 getJsonData()。我不需要更新这个json,我只需要阅读。
我使用 FutureBuilder 仅在读取所有数据后才开始绘制下拉菜单。
也许我有重复的项目,因为我再次调用 getJsonData()?
因为 null 我猜不是,因为该项目列在下拉列表中。仅当我选择一项时才会出现此问题。
感谢您的支持。
我在没有 FutureBuilder 的情况下尝试过,但问题是我正在读取一个空列表,因为当下拉列表读取列表时 json 没有及时准备好。
EDIT1:有人认为可以解决,但我认为这是不正确的,因为我创建了一个 bool started = false;在 getJsonData() 中我放了一个 if/else。因此,如果开始等于 true,我不会再次读取 json。我只返回相同的列表...但问题是,如果我决定创建一个动态列表并且需要再次读取该列表,那么我会收到错误!
EDIT2:另一个测试。在 getJsonData() 内部,我删除了 if/else 并在开头放置 modelsListLoaded.clear();但没有起作用。同样的错误。我之前尝试清除列表,但发生了同样的错误。
EDIT3:如果我删除所有 FutureBuilder 的东西并使用此代码:
@override
void initState() {
// TODO: implement initState
getJsonData();
super.initState();
}
工作得很好,但仅限于模拟器。在我的手机中不起作用,因为下拉列表仍然处于禁用状态,因为里面没有项目。但在模拟器中工作正常。几秒钟后,下拉列表从禁用更改为单独启用!!!
您应该将 StudentList 变量移动到 TestPageState 类中。
然后在 setState() 块内的 getJsonData 方法中更新它。例如:
void getJsonData() async {
final String response = await rootBundle.loadString('assets/students.json');
final data = await json.decode(response);
final newStudentList = await data.map<Students>((json) => Students.fromJson(json)).toList();
setState( () {
studentList = newStudentList ;
});
}
在 setState 调用中更新 StudentList 将导致再次调用 build() 方法,并且它将使用您分配给 StudentList 的新值。