Flutter:根据类型对 ListView 项进行排序
Posted
技术标签:
【中文标题】Flutter:根据类型对 ListView 项进行排序【英文标题】:Flutter: Sorting ListView items based on type 【发布时间】:2019-09-15 06:14:25 【问题描述】:所以我在 Flutter 的项目管理应用程序中有一个 listview.builder。这个列表视图充满了任务(它们可以是:新的、开始的、完成的)。我从 API 获取这些数据,并希望“新”的数据出现在顶部,开始出现在中间的数据和“完成”的数据的底部! - This is how it looks right now 这是我的类,请注意我从 API/JSON 获取状态
class ProjectTask
final int id;
final String description;
final String state;
final List assigned_users;
final List subtasks;
ProjectTask(this.id,
this.description,
this.state,
this.assigned_users,
this.subtasks);
列表视图
else return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index)
if(snapshot.data[index].state == "done")
return Slidable(
//SLIDABLE STUFF
delegate: SlidableStrechDelegate(),
actionExtentRatio: 0.25,
actions: <Widget>[
//ACTION ONE
IconSlideAction(
caption: ("Information"),
foregroundColor: Colors.white,
color: Colors.black38,
icon: Icons.info,
onTap: ()
Navigator.push(context, MaterialPageRoute(builder: (context)=>projectTask(snapshot.data[index])));
,
),
],
child: ListTile(
onTap: ()
Navigator.push(context, MaterialPageRoute(builder: (context) => projectTask(
snapshot.data[index],
)));
,
title: Text("$snapshot.data[index].description[0].toString().toUpperCase()"
"$snapshot.data[index].description.toString().substring(1)", maxLines: 1, style: TextStyle(
color: Colors.black87, fontSize: 17)
),
subtitle: Text("done"),
leading: Icon(Icons.check_circle, color: Colors.green),
trailing: Icon(Icons.arrow_right, color: Colors.black54,),
),
);
else if(snapshot.data[index].state == "started")
return Slidable(
//SLIDABLE STUFF
delegate: SlidableStrechDelegate(),
actionExtentRatio: 0.25,
actions: <Widget>[
//ACTION ONE
IconSlideAction(
caption: ("Information"),
foregroundColor: Colors.white,
color: Colors.black38,
icon: Icons.info,
onTap: ()
Navigator.push(context, MaterialPageRoute(builder: (context)=>projectTask(snapshot.data[index])));
,
),
],
secondaryActions: <Widget>[
//ACTION TWO
IconSlideAction(
caption: ("Complete Me"),
color: Colors.green,
icon: Icons.radio_button_checked,
onTap: ()
Navigator.push(context, MaterialPageRoute(builder: (context)=>projectTask(snapshot.data[index])));
,
)
],
child: ListTile(
onTap: ()
Navigator.push(context, MaterialPageRoute(builder: (context) => projectTask(
snapshot.data[index],
)));
,
title: Text("$snapshot.data[index].description[0].toString().toUpperCase()"
"$snapshot.data[index].description.toString().substring(1)", maxLines: 1, style: TextStyle(
color: Colors.black87, fontSize: 17)
),
subtitle: Text("working"),
leading: Icon(Icons.radio_button_checked, color: Colors.blue),
trailing: Icon(Icons.arrow_right, color: Colors.black54,),
),
);
else
return Slidable(
//SLIDABLE STUFF
delegate: SlidableStrechDelegate(),
actionExtentRatio: 0.25,
actions: <Widget>[
//ACTION ONE
IconSlideAction(
caption: ("Information"),
foregroundColor: Colors.white,
color: Colors.black38,
icon: Icons.info,
onTap: ()
Navigator.push(context, MaterialPageRoute(builder: (context)=>projectTask(snapshot.data[index])));
,
),
],
secondaryActions: <Widget>[
//ACTION TWO
IconSlideAction(
caption: ("Start Work"),
color: Colors.blue,
icon: Icons.radio_button_checked,
onTap: ()
Navigator.push(context, MaterialPageRoute(builder: (context)=>projectTask(snapshot.data[index])));
,
)
],
//LISTTILE
child: ListTile(
onTap: ()
Navigator.push(context, MaterialPageRoute(builder: (context) => projectTask(
snapshot.data[index],
)));
,
title: Text("$snapshot.data[index].description[0].toString().toUpperCase()"
"$snapshot.data[index].description.toString().substring(1)", maxLines: 1, style: TextStyle(
color: Colors.black87, fontSize: 17)
),
subtitle: Text("new"),
leading: Icon(Icons.radio_button_checked, color: Colors.red),
trailing: Icon(Icons.arrow_right, color: Colors.black54,),
),
);
);
JSON
[
"id": 7,
"description": "Finishedddddd",
"state": "done",
"assigned_users": [
"username": "hugo",
"fullname": "Hugo Johnsson"
],
"subtasks": []
,
"id": 9,
"description": "Newwww task for Huuugo",
"state": "started",
"assigned_users": [
"username": "hugo",
"fullname": "Hugo Johnsson"
],
"subtasks": []
,
"id": 11,
"description": "Google presentation om IKEAS ekonomi",
"state": "done",
"assigned_users": [
"username": "studentone",
"fullname": "Student One"
],
"subtasks": []
,
"id": 15,
"description": "entail",
"state": "new",
"assigned_users": [],
"subtasks": [
"id": 1,
"description": "dasdasdasd"
,
"id": 2,
"description": "fsdfsdfsdf"
]
,
"id": 17,
"description": "gmmgmsgd",
"state": "new",
"assigned_users": [],
"subtasks": []
,
"id": 18,
"description": "dasd",
"state": "started",
"assigned_users": [],
"subtasks": []
,
"id": 19,
"description": "fsdfdsfsd",
"state": "started",
"assigned_users": [],
"subtasks": []
,
"id": 20,
"description": "Werner",
"state": "new",
"assigned_users": [],
"subtasks": []
,
"id": 21,
"description": "teadfsd",
"state": "done",
"assigned_users": [],
"subtasks": []
,
"id": 22,
"description": "task",
"state": "new",
"assigned_users": [],
"subtasks": []
,
"id": 23,
"description": "asdasd",
"state": "started",
"assigned_users": [],
"subtasks": []
,
"id": 24,
"description": "asdasd",
"state": "new",
"assigned_users": [
"username": "hugo",
"fullname": "Hugo Johnsson"
],
"subtasks": []
]
【问题讨论】:
【参考方案1】:您应该在创建ListView
之前对数据进行排序。您可以使用基本的dart sort method。基本上你只需要实现compare function,它返回一个整数,返回值的符号指定项目顺序。
阅读此示例代码以更好地理解:
enum TaskState
newTask, done, started
class Task
Task(this.id, this.state);
final int id;
final TaskState state;
String toString()
return "$id";
int compare(TaskState a, TaskState b)
if (a == b) return 0;
switch(a)
case TaskState.newTask:
return -1;
break;
case TaskState.started:
if(b == TaskState.newTask) return 1;
return -1;
break;
case TaskState.done:
return 1;
break;
void main()
List<Task> list = [
Task(1, TaskState.done),
Task(3, TaskState.newTask),
Task(4, TaskState.started),
Task(2, TaskState.done),
Task(10, TaskState.newTask),
];
list.sort((a, b) => compare(a.state, b.state));
print(list);
在你的代码中实现应该是这样的
FutureBuilder<List<ProjectTask>>(
future: someQuery(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snap)
snap.data.sort((a, b) =>
if (a == b) return 0;
switch(a)
case "new":
return -1;
break;
case "started":
if(b == "new") return 1;
return -1;
break;
case "done":
return 1;
break;
);
return ListView.builder(
...
)
)
【讨论】:
谢谢,你能解释一下我将如何以一种好的方式实现它吗? :) 其实很简单。我已经编辑了答案并添加了一个实现以上是关于Flutter:根据类型对 ListView 项进行排序的主要内容,如果未能解决你的问题,请参考以下文章
Flutter ListView 项目根据 TextField 中添加的数字进行更改
Flutter 在 ListView 返回类型 String 中显示嵌套 json 不是类型转换中类型“Map<String, dynamic>”的子类型