Flutter 使用dart中的多个下拉列表筛选列表

Flutter 使用dart中的多个下拉列表筛选列表,flutter,dart,dropdown,Flutter,Dart,Dropdown,嘿,谢谢你检查我的问题,我正在制作一个应用程序,它连接到一个api并像这样提取json数据 我一直在尝试让一个过滤系统工作,例如,列表可以按某个系列和其他选项排序,我在代码中有两个列表,一个用于api的所有结果,称为_userdetails,另一个用于搜索结果,称为_searchresult 我的目标是让过滤器和搜索栏同步工作,例如,您可以筛选一个名为“一件”的系列,然后使用其他过滤器筛选新列表,以缩小结果范围,甚至在这些新列表上使用搜索栏 目前,我有过滤器工作到一定程度,如果该系列被选为龙珠

嘿,谢谢你检查我的问题,我正在制作一个应用程序,它连接到一个api并像这样提取json数据

我一直在尝试让一个过滤系统工作,例如,列表可以按某个系列和其他选项排序,我在代码中有两个列表,一个用于api的所有结果,称为_userdetails,另一个用于搜索结果,称为_searchresult

我的目标是让过滤器和搜索栏同步工作,例如,您可以筛选一个名为“一件”的系列,然后使用其他过滤器筛选新列表,以缩小结果范围,甚至在这些新列表上使用搜索栏

目前,我有过滤器工作到一定程度,如果该系列被选为龙珠,它将选择所有的龙珠字符,但一旦一个新的过滤器或搜索被使用,它只是重置列表 这是下拉列表的代码

new Row(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                 // Text("Select a series"),


                new  DropdownButton<String>(
                    hint: Text("Series"),
                   // value: null,

                    items: _fieldList.map((value){
                      return DropdownMenuItem<String>(
                        value: value.series,
                        child: Container(
                          width: 100,
                        child: new Text(value.series),
                       // height: 5.0,
                          ),
                      );
                    }).toList(),
                    onChanged: (String val) {
                      _selectedText = val;
                      setState(() {
                       // _searchResult.clear();
                      //  _searchResult.removeWhere((userDetail) => userDetail.series != _selectedText);
                         // _newList.clear();
                        _selectedText = val;
                        _userDetails.forEach((userDetail) {

                          if(userDetail.series.contains(_selectedText)){
                            userDetail.remove((userDetail) => userDetail.series != _selectedText);
                            _searchResult.add(userDetail);}
                          if(_searchResult.contains(_selectedText))
                            _searchResult.removeWhere((userDetail) => userDetail.series != _selectedText);

                          //   _userDetails.where((f) => f.series.contains(_selectedText)).toList(); //apples

                          print(_searchResult.length);

                        });
                        print(_selectedText);
                      });
                    },
                  ),

                 new DropdownButton<String>(
                    hint: Text("Class"),
                    // value: null,

                    items: _fieldList.map((value){
                      return DropdownMenuItem<String>(
                        value: value.classs,
                        child: new Text(value.classs),
                      );
                    }).toList(),
                    onChanged: (String val) {
                      _selectedText = val;
                      setState(() {

                        _searchResult.removeWhere((userDetail) => userDetail.classs != _selectedText);

                        _userDetails.forEach((userDetail) {
                        if (userDetail.classs.contains(_selectedText))
                          ///loops thrpugh each user detail and add where selectedtext = whatever
                        //  _searchResult.removeWhere((_searchResult) => userDetail.classs != _selectedText);
                          _searchResult.removeWhere((userDetail) => userDetail.classs != _selectedText);

                        _searchResult.add(userDetail);
                      //  _userDetails.where((f) => f.classs.contains(_selectedText)).toList(); //apples

                       /// _searchResult.add(userDetail);

                        });

                           // _searchResult.add(userDetail);
                          print(_selectedText);
                          //_searchResult.remove(userDetail.classs.)

                          //_newList.add(userDetail);
                          print(_searchResult.length);

                       // });
                        print(_selectedText);
                      });
                    },
                  ),
                  SizedBox(
                    height: 5.0,
                  ),
                  Text('Selected: ${_selectedText}'),
                ],
              ),

我有点困惑lol

在搜索或更改过滤器后,您不断重置列表的原因是您正在调用setstate并分配值_selectedText=val。您正在为selectedText分配新值

//Excerpt from your code

onChanged: (String val) {
      setState(() {
     /// When the dropdown value changes you are assigning a new value to selected 
     /// text
     /// Assuming it had Goto and the user selected Vegeta, the new value of 
     /// selectedText will be Vegeta
     _selectedText = val;
     // The statement that follows will evaluate based on the new value 
   });
  });
我建议要么使用面向对象的方法,从这些字段创建模型,并使用I、e系列和类,要么使用映射而不是字符串。如果您觉得使用字符串更合适,请使用与过滤器数量相等的字符串。i.e将所选文本转换为映射。由于您使用的是下拉菜单,我的假设是,您只需要每个过滤器中的一个值

///Initialize your set outside the build method and results
final Map<String,String> selected = {"series":"","class":""}

/// Initialized the results list with the initial result set 
List results = userDetails;

/// Method to build your results

void buildResults(){
  setState((){
    var seriesList = 

/// comparing strings in dart is case sensitive so 
///  depending on your data you may consider 
/// converting all the strings you are comparing to lowercase 
 _userList
 .where((userDetail)=>userDetail
 .series
 .toLowerCase()
  .contains(selected["series"]))).toList();

  var classList = 
  _userList
  .where((userDetail)=>userDetail
  .class.toLowerCase()
  .contains(selected["class"]))).toList();
 
  /// Merge the two lists using spread operator
  /// Assuming you are using Dart > 2.3
  var list3 = [...seriesList, ...classList];

  results = list3;
 
});
}

/// onChanged method of Dropdown button
/// Assuming this is the series dropdown
setState((){
  selected.update(
   "series", 
    // if it is already in the map
   (existingValue) => value, 
   ifAbsent: () => value,
 );
buildResults();
});






 /// In your listview builder
 ListView.builder(
 itemCount: results.length, 
 itemBuilder:(context,index){
}
///在生成方法和结果之外初始化集合
选择的最终映射={“系列”:““类”:”}
///使用初始结果集初始化结果列表
列表结果=用户详细信息;
///方法来生成结果
void buildResults(){
设置状态(){
变量系列列表=
///在dart中比较字符串区分大小写,因此
根据你的数据,你可以考虑
///将要比较的所有字符串转换为小写
_用户列表
.其中((userDetail)=>userDetail
系列
.toLowerCase()
.contains(选定的[“系列]))).toList();
变量类列表=
_用户列表
.其中((userDetail)=>userDetail
.class.toLowerCase()
.contains(选定的[“类]))).toList();
///使用扩展运算符合并两个列表
///假设您使用的Dart>2.3
var list3=[…系列列表,…类列表];
结果=列表3;
});
}
///下拉按钮的一次更改方法
///假设这是序列下拉列表
设置状态(){
已选择。更新(
“系列”,
//如果它已经在地图上了
(现有值)=>值,
ifAbsent:()=>值,
);
buildResults();
});
///在listview生成器中
ListView.builder(
itemCount:results.length,
itemBuilder:(上下文,索引){
}
你可以找到一个更有效的方法。你不需要调用setstate两次,我已经这样做了

///Initialize your set outside the build method and results
final Map<String,String> selected = {"series":"","class":""}

/// Initialized the results list with the initial result set 
List results = userDetails;

/// Method to build your results

void buildResults(){
  setState((){
    var seriesList = 

/// comparing strings in dart is case sensitive so 
///  depending on your data you may consider 
/// converting all the strings you are comparing to lowercase 
 _userList
 .where((userDetail)=>userDetail
 .series
 .toLowerCase()
  .contains(selected["series"]))).toList();

  var classList = 
  _userList
  .where((userDetail)=>userDetail
  .class.toLowerCase()
  .contains(selected["class"]))).toList();
 
  /// Merge the two lists using spread operator
  /// Assuming you are using Dart > 2.3
  var list3 = [...seriesList, ...classList];

  results = list3;
 
});
}

/// onChanged method of Dropdown button
/// Assuming this is the series dropdown
setState((){
  selected.update(
   "series", 
    // if it is already in the map
   (existingValue) => value, 
   ifAbsent: () => value,
 );
buildResults();
});






 /// In your listview builder
 ListView.builder(
 itemCount: results.length, 
 itemBuilder:(context,index){
}