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

Flutter 在flatter中对未来列表进行排序,flutter,sorting,mobile,flutter-layout,Flutter,Sorting,Mobile,Flutter Layout,我一直在寻找一种解决方案,在FutureBuilder内部的按钮上对列表进行排序(升序和降序),这是一个未来的,但似乎不明白如何将其定义为列表,然后在按钮上对其进行排序。所以我调用API,API返回一些伪值,它在未来的构建器和ListView.Builder中构建,现在我想按id(或任何类型)对列表进行排序,但该方法不起作用,因为列表为空。守则: 虚拟数据的API调用: Future<List<Post>> fetchPosts() async { List<P

我一直在寻找一种解决方案,在
FutureBuilder
内部的
按钮上对列表进行排序(升序和降序)
,这是一个
未来的
,但似乎不明白如何将其定义为列表,然后在按钮上对其进行排序。所以我调用API,API返回一些伪值,它在未来的构建器和
ListView.Builder
中构建,现在我想按id(或任何类型)对列表进行排序,但该方法不起作用,因为列表为空。守则:

虚拟数据的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');
  }
}

Future fetchPosts()异步{
名单员额=[];
最终响应=等待http.get('https://jsonplaceholder.typicode.com/posts');
如果(response.statusCode==200){
//如果服务器确实返回了200 OK响应,
//然后解析JSON。
var postsJson=jsonDecode(response.body);
for(int i=0;i
未来的建设者:

 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();
                  },
                ),
List posts=[];//如果a这样定义它,则该值始终为空
未来职位;
@凌驾
void initState(){
super.initState();
futurePosts=fetchPosts();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
背景颜色:Colors.white,
正文:安全区(
子:SingleChildScrollView(
滚动方向:轴垂直,
子:列(
儿童:[
MaterialButton(颜色:Colors.grey,按下时)(){
//在这里,我将设置为比较所有ID的值,以便每次按下按钮时可以按ID的数量升序和降序排序
设置状态(){
posts.sort((a,b)=>a.id.compareTo(b.id));
});
},),
容器(
身高:1000,
孩子:未来建设者(
未来:未来邮报,
生成器:(上下文,快照){
if(snapshot.hasData){
返回ListView.builder(
收缩膜:对,
itemCount:snapshot.data.length,
itemBuilder:(上下文,索引){
返回文本(“${snapshot.data[index].id}”)
},
);
}else if(snapshot.hasrerror){
返回文本(“${snapshot.error}”);
}
返回容器();
},
),

但是我的理解和代码在这一点上似乎对我不起作用。感谢您的帮助,提前感谢!

您可以将您的
帖子进行排序((a,b)=>a.id.compareTo(b.id))
在您的Future函数中,在返回
posts
之前,更改setState,以更改布尔值的状态,无论是否排序

您可以这样更改:

//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<List<Post>>(
 future:_isSorted? fetchPosts(true):fetchPosts(false),
 builder: (context, snapshot) {
 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(),
          )
        ]),
      ),
    ),
  );
}
列出帖子;
@凌驾
void initState(){
super.initState();
fetchPosts()。然后((项){
设置状态(){
员额=项目;
});
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
背景颜色:Colors.white,
正文:安全区(
子:SingleChildScrollView(
滚动方向:轴垂直,
子项:列(子项:[
材料按钮(
颜色:颜色。灰色,
已按下:(){
设置状态(){
if(posts!=null){
posts=posts.toList();
posts.sort((a,b)=>a.id.compareTo(b.id));
}
});
},
),
容器(
身高:1000,
子:(posts!=null)
?ListView.builder(
收缩膜:对,
itemCount:posts.length,
itemBuilder:(上下文,索引){
返回文本(“${posts[index].id}”);
},
)
:Container(),
)
]),
),
),
);
}

您的
posts
字段始终为空,因为您从未将数据分配给该字段。这是主要问题。请尝试。

在多次显示数据时,您似乎需要
StreamBuilder
而不是
FutureBuilder
,以便触发您最可能需要的
builder:
属性回调一个
StreamController.add
methodOk,也许你有点道理,但排序方法是否保持不变?这是我的问题,排序,我可以尝试使用
StreamBuilder
…谢谢,伙计,但是
方法“sort”不是为类型“Future”定义的。
,因为我调用的是一个API,它是Future而不是List,有什么用关于这一点?在哪里调用
sort
?当我在
initState()中调用API时,需要在
posts
class字段上调用它
,因为它是一个未来,我必须像
未来列表那样定义它;
所以在我想要排序的按钮中,我得到
方法“sort”没有为类型“Future”定义。
我试过,但它不起作用,当我打印出
\u isSorted
时,它确实变为true和false,但列表保持不变,它是not按ID值排序。每当我单击该按钮时,它有时在API中调用,有时不调用:
I/flatter(5048):在构建器外部:false I/flatter(5048):在API中:true I/flatter(5048):在构建器外部:true I/flatter(5048):在构建器外部:false I/flatter(5048):在API中:tr