来自 webservice 的元素不会出现在 Flutter 的拖放列表中
Elements from webservice doesn't appear in Drag and drop List in Flutter
我已经用静态数据构建了一个拖放列表,效果很好,现在当我尝试从网络服务添加数据时,它没有显示在小部件中(它只显示静态数据):
但与此同时,当我在控制台中对列表执行 print() 操作时,它会显示所有数据(静态数据和来自网络服务的数据):
这是我的代码:
class Taches extends StatefulWidget{
@override
TachesState createState(){
return new TachesState();
}
}
class TachesState extends State<Taches> {
//the static data
List<String> listeTaches = [
'Tâche 1',
'Tâche 2',
'Tâche 3',
'Tâche 4',
'Tâche 5',
'Tâche 6',
'Tâche 7',
'Tâche 8',
'Tâche 9',
'Tâche 10',
];
void getTaches() async {
Session session = new Session();
var taches = jsonDecode(await session.authentification());
//here I add the data from the webservice
for(int i = 0; i < taches['result']["inRangeTasks"].length ; i++){
var tacheStr = taches['result']["inRangeTasks"][i]['name'];
listeTaches.add(tacheStr.toString());
}
print(listeTaches);
}
_onReorder(oldIndex, newIndex) {
setState((){
if(newIndex > oldIndex){
newIndex -= 1;
}
var item = listeTaches.removeAt(oldIndex);
listeTaches.insert(newIndex, item);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
title: Text('Beotic Project'),
centerTitle: true,
),
body: ReorderableListView(
header: Center(
child: Container(
child: Text(
'Listes des tâches',
style: Theme.of(context).textTheme.headline5,
),
padding: EdgeInsets.symmetric(vertical: 20)
)
),
children: listeTaches.map((e) => ListTile(
key: UniqueKey(),
leading: Icon(Icons.task),
title: Text(e),
trailing: Icon(Icons.more_vert),
)).toList(),
onReorder: _onReorder,
),
);
}
@override
void initState(){
//I directly call, in the initState function, the function which extract the data from the webservice and put it in the list
getTaches();
}
}
我的目标是让列表中的所有数据都显示在小部件上,
可能是我做错了什么,
感谢您的帮助!
你的代码的问题在于,虽然 getTaches()
是一个 async
函数,但你不能 await
它在 initState
中,因为 initState
不能是异步函数。因此,您的 ReorderableListView
将在数据返回并添加到 getTaches()
函数中的 listeTaches
之前构建。
解决方案是使用 FutureBuilder
,并且仅在 future(获取)完成后才构建小部件。检查以下代码。我简化了它并模拟了延迟和后端调用,但您可以看到它是如何工作的并根据您的需要进行调整。
import 'package:flutter/material.dart';
void main() => runApp(
const MaterialApp(
home: Scaffold(body: Taches()),
),
);
class Taches extends StatefulWidget {
const Taches({Key? key}) : super(key: key);
@override
TachesState createState() => TachesState();
}
class TachesState extends State<Taches> {
//the static data
List<String> listeTaches = [
'Tâche 1',
'Tâche 2',
'Tâche 3',
'Tâche 4',
'Tâche 5',
'Tâche 6',
'Tâche 7',
'Tâche 8',
'Tâche 9',
'Tâche 10',
];
Future<List<String>> getTaches() async {
return Future.delayed(const Duration(milliseconds: 2000), () {
for (int i = 11; i <= 20; i++) {
listeTaches.add('Tâche $i');
}
return listeTaches;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: FutureBuilder<List<String>>(
future:
getTaches(), // a previously-obtained Future<String> or null
builder: (BuildContext context,
AsyncSnapshot<List<String>> snapshot) {
if (snapshot.hasError) {
// manage error
return const Text('Error');
}
// no error and we have data
if (snapshot.hasData) {
return ReorderableListView(
header: Center(
child: Text(
'Listes des tâches',
style: Theme.of(context).textTheme.headline5,
)),
children: listeTaches
.map((e) => ListTile(
key: UniqueKey(),
leading: const Icon(Icons.task),
title: Text(e),
trailing: const Icon(Icons.more_vert),
))
.toList(),
onReorder: (oldIndex, newIndex) => {},
);
}
// show initial data while loading
return const Center(child: CircularProgressIndicator());
})));
}
}
我已经用静态数据构建了一个拖放列表,效果很好,现在当我尝试从网络服务添加数据时,它没有显示在小部件中(它只显示静态数据):
但与此同时,当我在控制台中对列表执行 print() 操作时,它会显示所有数据(静态数据和来自网络服务的数据):
这是我的代码:
class Taches extends StatefulWidget{
@override
TachesState createState(){
return new TachesState();
}
}
class TachesState extends State<Taches> {
//the static data
List<String> listeTaches = [
'Tâche 1',
'Tâche 2',
'Tâche 3',
'Tâche 4',
'Tâche 5',
'Tâche 6',
'Tâche 7',
'Tâche 8',
'Tâche 9',
'Tâche 10',
];
void getTaches() async {
Session session = new Session();
var taches = jsonDecode(await session.authentification());
//here I add the data from the webservice
for(int i = 0; i < taches['result']["inRangeTasks"].length ; i++){
var tacheStr = taches['result']["inRangeTasks"][i]['name'];
listeTaches.add(tacheStr.toString());
}
print(listeTaches);
}
_onReorder(oldIndex, newIndex) {
setState((){
if(newIndex > oldIndex){
newIndex -= 1;
}
var item = listeTaches.removeAt(oldIndex);
listeTaches.insert(newIndex, item);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
title: Text('Beotic Project'),
centerTitle: true,
),
body: ReorderableListView(
header: Center(
child: Container(
child: Text(
'Listes des tâches',
style: Theme.of(context).textTheme.headline5,
),
padding: EdgeInsets.symmetric(vertical: 20)
)
),
children: listeTaches.map((e) => ListTile(
key: UniqueKey(),
leading: Icon(Icons.task),
title: Text(e),
trailing: Icon(Icons.more_vert),
)).toList(),
onReorder: _onReorder,
),
);
}
@override
void initState(){
//I directly call, in the initState function, the function which extract the data from the webservice and put it in the list
getTaches();
}
}
我的目标是让列表中的所有数据都显示在小部件上,
可能是我做错了什么,
感谢您的帮助!
你的代码的问题在于,虽然 getTaches()
是一个 async
函数,但你不能 await
它在 initState
中,因为 initState
不能是异步函数。因此,您的 ReorderableListView
将在数据返回并添加到 getTaches()
函数中的 listeTaches
之前构建。
解决方案是使用 FutureBuilder
,并且仅在 future(获取)完成后才构建小部件。检查以下代码。我简化了它并模拟了延迟和后端调用,但您可以看到它是如何工作的并根据您的需要进行调整。
import 'package:flutter/material.dart';
void main() => runApp(
const MaterialApp(
home: Scaffold(body: Taches()),
),
);
class Taches extends StatefulWidget {
const Taches({Key? key}) : super(key: key);
@override
TachesState createState() => TachesState();
}
class TachesState extends State<Taches> {
//the static data
List<String> listeTaches = [
'Tâche 1',
'Tâche 2',
'Tâche 3',
'Tâche 4',
'Tâche 5',
'Tâche 6',
'Tâche 7',
'Tâche 8',
'Tâche 9',
'Tâche 10',
];
Future<List<String>> getTaches() async {
return Future.delayed(const Duration(milliseconds: 2000), () {
for (int i = 11; i <= 20; i++) {
listeTaches.add('Tâche $i');
}
return listeTaches;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: FutureBuilder<List<String>>(
future:
getTaches(), // a previously-obtained Future<String> or null
builder: (BuildContext context,
AsyncSnapshot<List<String>> snapshot) {
if (snapshot.hasError) {
// manage error
return const Text('Error');
}
// no error and we have data
if (snapshot.hasData) {
return ReorderableListView(
header: Center(
child: Text(
'Listes des tâches',
style: Theme.of(context).textTheme.headline5,
)),
children: listeTaches
.map((e) => ListTile(
key: UniqueKey(),
leading: const Icon(Icons.task),
title: Text(e),
trailing: const Icon(Icons.more_vert),
))
.toList(),
onReorder: (oldIndex, newIndex) => {},
);
}
// show initial data while loading
return const Center(child: CircularProgressIndicator());
})));
}
}