繁体   English   中英

在 Flutter 中对未来列表进行排序

[英]Sorting a Future List in Flutter

我一直在寻找一种解决方案来对列表进行排序(升序和降序) On Button PressFutureBuilder内,即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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM