[英]Sorting a Future List in Flutter
我一直在寻找一种解决方案来对列表进行排序(升序和降序) On Button Press
在FutureBuilder
内,即Future<List>
,但似乎无法理解如何将其定义为 List 然后排序它按一个按钮。 所以我调用 API,API 返回一些虚拟值,它是在 Future Builder 和ListView.builder
中构建的,现在我想按 id (或任何类型)对列表进行排序,但该方法不起作用因为列表是 null。 编码:
API 调用虚拟数据:
Future<List<Post>> fetchPosts() async {
List<Post> posts = [];
final response = await http.get('https://jsonplaceholder.typicode.com/posts');
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
var postsJson = jsonDecode(response.body);
for (int i = 0; i < postsJson.length; i++) {
posts.add(Post.fromJson(jsonDecode(response.body)[i]));
}
return posts;
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load posts');
}
}
未来建设者:
List<Post> posts = []; /// if a define it like this, the value is always null
Future<List<Post>> futurePosts;
@override
void initState() {
super.initState();
futurePosts = fetchPosts();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
MaterialButton(color: Colors.grey, onPressed: (){
// here I am setting set to compare the values of all IDs so it can be sorted ascending and descending by number of ID every time I press the button
setState(() {
posts.sort((a, b) => a.id.compareTo(b.id));
});
},),
Container(
height: 1000,
child: FutureBuilder<List<Post>>(
future: futurePosts,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Text('${snapshot.data[index].id}')
},
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Container();
},
),
但在这一点上,我的理解和代码似乎对我不起作用。 任何帮助表示赞赏,在此先感谢!
您可以移动您的posts.sort((a, b) => a.id.compareTo(b.id));
在您的 Future function 中,在返回posts
之前。 并更改 setState,以更改 boolean 的 state,排序与否。
你可以这样改变:
//define a boolen
bool _isSorted =false;
Future<List<Post>> fetchPosts(bool sortORnot) async {
List<Post> posts = [];
final response = await http.get('https://jsonplaceholder.typicode.com/posts');
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
var postsJson = jsonDecode(response.body);
for (int i = 0; i < postsJson.length; i++) {
posts.add(Post.fromJson(jsonDecode(response.body)[i]));
}
if (sortORnot) {posts.sort((a, b) => a.id.compareTo(b.id));}// this will sort only if you wanted your list sorted.
return posts;
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load posts');
}
}
将您的FutureBuilder
更改为:
FutureBuilder<List<Post>>(
future:_isSorted? fetchPosts(true):fetchPosts(false),
builder: (context, snapshot) {
和setState
到这个:
setState(() {
_isSorted = !_isSorted; //this flips the value whenever you press it.
});
现在,在您未来的构建器中,您应该对帖子进行排序,您可以试试这个吗?
我认为这样的事情应该有效:
List<Post> posts;
@override
void initState() {
super.initState();
fetchPosts().then((items) {
setState(() {
posts = items;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(children: [
MaterialButton(
color: Colors.grey,
onPressed: () {
setState(() {
if (posts != null) {
posts = posts.toList();
posts.sort((a, b) => a.id.compareTo(b.id));
}
});
},
),
Container(
height: 1000,
child: (posts != null)
? ListView.builder(
shrinkWrap: true,
itemCount: posts.length,
itemBuilder: (context, index) {
return Text('${posts[index].id}');
},
)
: Container(),
)
]),
),
),
);
}
您的posts
字段始终为空,因为您从未将数据分配给该字段。 这是主要问题。 试试看。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.