我正在尝试使用 API 的结果填充我的 ListView。API 调用必须在从共享首选项中检索到值之后进行。但是,在执行时,我的 API 调用函数会运行一个无限循环,并且 UI 不会呈现。我通过调试语句跟踪了这种行为。
Future builder 构建 UI 时应该显示的圆形指示器也没有显示。
我该如何解决这个问题?
我的代码:
class _MyHomePageState extends State<MyHomePage>{
@override MyHomePage get widget => super.widget;
String userID = "";
String authID = "";
//Retrieving values from Shared Preferences
Future<List<String>> loadData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> l= new List<String>();
if(prefs.getString("ID") == null){
l.add("null");
}
else{
l.add(prefs.getString("ID"));
}
if(prefs.getString("authID") == null){
l.add("null");
}
else{
l.add(prefs.getString("authID"));
}
return l;
}
//Setting values retrieved from Shared Pref
setData() async{
await loadData().then((value) {
setState(() {
userID = value[0];
print('the user ID is' + userID);
authID = value[1];
print('the authID is' + authID);
});
// getAllTasks(userID, authID);
});
print("Set data execution completed ");
}
//FUNCTION to use values from Shared Pref and make API Call
Future<List<Task>> getAllTasks() async{
await setData();
//Waiting for Set Data to complete
print('Ive have retrived the values ' + userID + authID );
List<Task> taskList;
await getTasks(userID, authID, "for_me").then((value){
final json = value;
if(json!="Error"){
Tasks tasks = tasksFromJson(json); //of Class Tasks
taskList = tasks.tasks; //getting the list of tasks from class
}
});
if(taskList != null) return taskList;
else {
print('Tasklist was null ');
throw new Exception('Failed to load data ');
}
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context){
_signedOut(){
widget.onSignedOut();
}
//To CREATE LIST VIEW
Widget createTasksListView(BuildContext context, AsyncSnapshot snapshot) {
var values = snapshot.data;
return ListView.builder(
itemCount: values == null ? 0 : values.length,
itemBuilder: (BuildContext context, int index) {
return values.isNotEmpty ? Ink(....
) : CircularProgressIndicator();
},
);
}
//MY COLUMN VIEW
Column cardsView = Column(
children: <Widget>[
....
Expanded(
child: FutureBuilder(
future: getAllTasks(),
initialData: [],
builder: (context, snapshot) {
return createTasksListView(context, snapshot);
}),
),
],
);
return Scaffold(
body: cardsView,
);
}
}
Run Code Online (Sandbox Code Playgroud)
而不是被调用一次......我的 setData 函数被重复调用......我该如何解决这个......请帮忙
Gun*_*han 14
您Future在每次重建小部件时都在创建对象。并且由于您在方法setState内部调用setData,因此它会递归地触发重建。
要解决此问题,您必须保留对Future对象的引用。并使用该参考FutureBuilder然后它可以理解它是以前使用的。
例如:
Future<List<Task>> _tasks;
@override
void initState() {
_tasks = getAllTasks();
super.initState();
}
Run Code Online (Sandbox Code Playgroud)
在你的小部件树中,像这样使用它:
Expanded(
child: FutureBuilder(
future: _tasks,
initialData: [],
builder: (context, snapshot) {
return createTasksListView(context, snapshot);
}),
),
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3672 次 |
| 最近记录: |