You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter自定义列表排序:按ID/评分排序并通过抽屉触发重排

解决按自定义字段排序ListView的问题

我明白你想要实现按id或rating字段对列表进行排序,并且点击侧边抽屉按钮后更新UI的需求。smooth_sort包确实只针对索引排序,不适合你的场景,不过Dart内置的List.sort()方法完全可以满足自定义字段排序的需求,下面是具体的解决方案:

步骤1:初始化列表并添加排序逻辑

首先,确保你的addressData有初始值避免空指针,然后添加一个自定义排序方法,通过指定字段和排序方向来处理排序:

class _MapAddressListingScreenState extends State<MapAddressListingScreen> with AfterLayoutMixin<MapAddressListingScreen> { 
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); 
  // 初始化空列表,避免空指针异常
  List addressData = []; 

  // 自定义排序方法:按指定字段和升降序排序
  void _sortAddressData(String sortField, bool isAscending) {
    setState(() {
      addressData.sort((a, b) {
        // 处理rating字段排序(假设rating是数字类型,若为字符串需先转换)
        if (sortField == 'rating') {
          final ratingA = a['rating'] as num;
          final ratingB = b['rating'] as num;
          return isAscending ? ratingA.compareTo(ratingB) : ratingB.compareTo(ratingA);
        } 
        // 处理id字段排序
        else if (sortField == 'id') {
          final idA = a['id'] as num;
          final idB = b['id'] as num;
          return isAscending ? idA.compareTo(idB) : idB.compareTo(idA);
        }
        return 0;
      });
    });
  }

  // 原有的afterFirstLayout和_getAddress方法保持不变
  @override 
  void afterFirstLayout(BuildContext context) { 
    _getAddress(); 
  } 

  _getAddress() { 
    List requestedLatlong = ModalRoute.of(context).settings.arguments; 
    print("============================Address Data"); 
    print(requestedLatlong); 
    setState(() { 
      addressData = requestedLatlong; 
    }); 
  } 

  // 原有的_addressData和itemCard方法保持不变
  List<Widget> _addressData() { 
    List<Widget> _address = []; 
    for (int i = 0; i < addressData.length; i++) { 
      _address.add( 
        GestureDetector( 
          onTap: () { 
            print('address list taped'); 
            AddWalkinModel model = widget.addWalkinModel; 
            print("After model"); 
            model.fromMap = false; 
            model.fromMapListing = true; 
            model.autoAssign = addressData[i]['autoAssign']; 
            model.branchId = addressData[i]['branchId']; 
            model.branchServiceId = addressData[i]['branchServiceId']; 
            print("After Model Model"); 
            Navigator.push( 
              context, 
              MaterialPageRoute( 
                builder: (context) => DynamicScreen( 
                  addWalkinModel: model, 
                ), 
              ), 
            ); 
          }, 
          child: AddressListingTile(listingTileData: addressData[i]), 
        ), 
      ); 
    } 
    return _address; 
  } 

  Widget itemCard() { 
    return Container( 
      child: Column( 
        children: _addressData(), 
      ), 
    ); 
  } 

步骤2:修改侧边抽屉的排序按钮

把原来的单个排序按钮替换成多个选项,让用户选择按哪个字段、哪种顺序排序:

@override 
  Widget build(BuildContext context) { 
    var colorStyles = Theming.colorstyle(context); 
    return Scaffold( 
      key: _scaffoldKey, 
      backgroundColor: colorStyles['primary'], 
      appBar: AppBar( 
        title: Text("BSP Listview "), 
        centerTitle: true, 
        elevation: 0, 
        leading: IconButton( 
          icon: Icon(Icons.arrow_back_ios), 
          onPressed: () { 
            Navigator.pop(context); 
          }, 
        ), 
        actions: <Widget>[ 
          IconButton( 
            icon: Icon(Icons.sort), 
            onPressed: () { 
              _scaffoldKey.currentState.openEndDrawer(); 
            }, 
          ), 
        ], 
      ), 
      endDrawer: Drawer( 
        child: Column( 
          children: <Widget>[ 
            SizedBox(height: 100), 
            FlatButton( 
              onPressed: () => _sortAddressData('rating', true), 
              child: Text("按Rating升序排序"), 
            ), 
            FlatButton( 
              onPressed: () => _sortAddressData('rating', false), 
              child: Text("按Rating降序排序"), 
            ), 
            FlatButton( 
              onPressed: () => _sortAddressData('id', true), 
              child: Text("按ID升序排序"), 
            ), 
            FlatButton( 
              onPressed: () => _sortAddressData('id', false), 
              child: Text("按ID降序排序"), 
            ), 
          ], 
        ), 
      ), 
      body: Stack( 
        children: <Widget>[ 
          Container( 
            child: ClipRRect( 
              borderRadius: new BorderRadius.only( 
                topLeft: const Radius.circular(30.0), 
                topRight: const Radius.circular(30.0)), 
              child: Stack( 
                children: <Widget>[ 
                  SingleChildScrollView( 
                    child: Container( 
                      child: Column( 
                        mainAxisAlignment: MainAxisAlignment.start, 
                        crossAxisAlignment: CrossAxisAlignment.start, 
                        children: <Widget>[ 
                          itemCard(), 
                        ], 
                      ), 
                    ), 
                  ) 
                ], 
              ), 
            ), 
          ), 
        ], 
      ), 
    ); 
  } 
}

关键说明

  • Dart的List.sort()方法允许传入自定义的比较函数,你可以直接对比两个元素的rating或id字段,实现完全自定义的排序逻辑。
  • 调用setState()会触发UI重建,排序后的列表会自动更新到ListView中。
  • 如果你的rating或id是字符串类型,记得在比较前转换成数字(比如int.parse(a['id'])),避免字符串排序的异常结果。

内容的提问来源于stack exchange,提问作者Rutvik Gumasana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:12:54