如何在 Flutter 中对 DataTable 小部件上的 Future<List> 数据类型进行排序?

Posted

技术标签:

【中文标题】如何在 Flutter 中对 DataTable 小部件上的 Future<List> 数据类型进行排序?【英文标题】:How to sort a Future<List> data type on DataTable widget in Flutter? 【发布时间】:2022-01-15 14:35:57 【问题描述】:

我在从 DataTable 小部件中的 Future 数据类型中排序列表时遇到问题

class User 
  final String idUser,
  name,
  phone;

  User(
    this.idUser,
    this.name,
    this.phone);

  factory User.fromJson(Map<String, dynamic> json) 
    return User(
    idUser: json['_id'],
    name: json['name'],
    phone: json['phone']);
  


List<User> userFromJson(jsonData) 
  List<User> result =
    List<User>.from(jsonData.map((item) => User.fromJson(item)));

  return result;


// index
Future<List<User>> fetchUser() async 
  String route = AppConfig.API_ENDPOINT + "userdata";
  final response = await http.get(route);
  if (response.statusCode == 200) 
    var jsonResp = json.decode(response.body);

    return userFromJson(jsonResp);
   else 
    throw Exception('Failed load $route, status : $response.statusCode');
  

我不想在 FutureBuilder 小部件内的 DataTable 小部件上调用它

int sortColumnIndex=0;
bool isAscending = true;
bool sort=false;
Future<List<User>> user;
User = fetchUser();

@override
  Widget build(BuildContext context) 
     return FutureBuilder(
        future: user,
        builder: (context, snapshot) 
          if(!snapshot.hasData) 
            return Center(child: CircularProgressIndicator());
          

          if(snapshot.hasData) 
            return Column(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              verticalDirection: VerticalDirection.down,
              children: <Widget>[
                // Table
                Expanded(
                  child: ListView(
                    children: [
                      Container(
                        padding: EdgeInsets.all(5),
                        child: dataBody(snapshot.data)
                      ),
                    ],
                  ),
                ),                  
              ],
            );
          
          return Center();            
        ,
      );
    

dataBody函数是:

SingleChildScrollView dataBody(List<User> listUser) 
  return SingleChildScrollView(
    scrollDirection: Axis.horizontal,
    child: DataTable(
      sortAscending: isAscending,
      sortColumnIndex: sortColumnIndex,
      showCheckboxColumn: false,
      columns: [
        DataColumn(
          label: Text("Name"),
          numeric: false,
          tooltip: "Name",
          onSort: (columnIndex, ascending)  
            setState(() sort = !sort;
            );
            onSortColumn(columnIndex, ascending);
          ),
        DataColumn(
            label: Text("Phone"),
            numeric: false,
            tooltip: "Phone"
        ),       
    ],
    
    rows: listUser
      .map(
        (user) => DataRow(
        onSelectChanged: (b) 
          print(user.name);
        ,
        cells: [
          DataCell(
              Text(user.name)
          ),
          DataCell(
              Text(user.phone)
          ),
        ]),
      ).toList(),
    ),
  );

而onSortColumn函数是这样的:

onSortColumn(int columnIndex, bool ascending) 
  if (columnIndex == 0) 
    if (ascending) 
      user.sort((a, b) => a.name.compareTo(b.name));
     else 
      user.sort((a, b) => b.name.compareTo(a.name));
    
  

就像“onSortColumn”中的“sort”这个词变成红色下划线并给出这样的消息:

没有为“Future”类型定义方法“sort”。 尝试将名称更正为现有方法的名称,或定义名为“排序”的方法。

如果有其他的排序方法,请告诉我,非常感谢

【问题讨论】:

您必须访问listUser 而不是useruserFuture,应该由FutureBuilder 处理,而来自完整Future 的实际数据是snapshot.data,它被赋予函数dataBody 的参数为listUser,所以你参考这里有一个错误的变量。 等等,我不是很清楚,所以根据它,什么变量需要替换,什么变量必须替换它? 哦,我明白了,非常感谢,也请在回答部分回答以方便其他人 【参考方案1】:
int sortColumnIndex=0;
bool isAscending = true;
bool sort=false;
Future<List<User>> userList;
List<User> users;
User = fetchUser();

@override
 Widget build(BuildContext context) 
   return FutureBuilder(
     future: userList,
     builder: (context, snapshot) 
       if(!snapshot.hasData) 
         return Center(child: CircularProgressIndicator());
       

       if(snapshot.hasData) 
          users = snapshot.data;
          return Column(
            mainAxisSize: MainAxisSize.min,
            mainAxisAlignment: MainAxisAlignment.center,
            verticalDirection: VerticalDirection.down,
            children: <Widget>[
            // Table
            Expanded(
              child: ListView(
                children: [
                  Container(
                    padding: EdgeInsets.all(5),
                    child: dataBody(users)
                  ),
                ],
              ),
            ),                  
          ],
        );
      
      return Center();            
    ,
  );

然后进行排序功能

onSortColumn(int columnIndex, bool ascending) 
  if (columnIndex == 0) 
    if (ascending) 
      users.sort((a, b) => a.name.compareTo(b.name));
     else 
      users.sort((a, b) => b.name.compareTo(a.name));
    
  

【讨论】:

但我直接使用 dataBody(snapshot.data) 获得了更有效的方法

以上是关于如何在 Flutter 中对 DataTable 小部件上的 Future<List> 数据类型进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 的 DataTable 中监听 DataRow 的点击

如何在 Flutter/Dart 中使用 Hive 框和索引以简单的方式将数据动态加载到 DataTable?

如何在 Flutter 中对列表进行排序 [重复]

使用 Firestore 和 Flutter 填充 DataTable(使用 StreamBuilder)

如何在 Flutter 中对依赖于 3rd-Party-Package 的代码进行单元测试?

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