簡體   English   中英

在 dart 中過濾具有多個下拉列表的列表

[英]filter a list with multiple dropdowns in dart

嘿,感謝您檢查我的問題,我正在制作一個連接到 api 並像這樣拉回 json 數據的應用程序

主屏幕 我一直在嘗試讓過濾系統正常工作,例如列表可以按某個系列和其他選項排序,我在代碼中有兩個列表,一個是來自名為 _userdetails 的 api 的所有結果,另一個是用於搜索結果稱為_searchresult。

我的目標是讓過濾器和搜索欄同步工作,例如,您可以過濾一個名為 onepiece 的系列,然后使用其他過濾器過濾該新列表以縮小結果范圍,甚至在這些新列表上使用搜索欄列表。

目前我有過濾器在一定程度上工作,如果系列被選為龍珠,它將選擇所有龍珠字符,但一旦使用新過濾器或搜索,它只會重置列表,這里是下拉列表的代碼

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}'),
                ],
              ),

這是列表視圖的代碼

new Expanded(
            child: _searchResult.length != 0 || controller.text.isNotEmpty
                ? new ListView.builder(
              itemCount: _searchResult.length,
              itemBuilder: (context, i) {
                return new Card(
                  child: new ListTile(
                    leading: new CircleAvatar(backgroundImage: new NetworkImage("https://ochd.co.uk/db/puti/Assets/Portraits/"+_searchResult[i].portrait,),),
                    title: new Text(_searchResult[i].name),
                    subtitle: new Text(_searchResult[i].classs),
                    onTap: () {
                      Navigator.push(context, new MaterialPageRoute(builder: (context) => DetailPage(_searchResult[i])));},
                  ),
                  margin:
                  const EdgeInsets.all(0.0),
                );
              },
            )
                : new ListView.builder(
              itemCount: _userDetails.length,
              itemBuilder: (context, index) {
                return new Card(
                  child: new ListTile(
                    leading: new CircleAvatar(backgroundImage: new NetworkImage("https://ochd.co.uk/db/puti/Assets/Portraits/"+_userDetails[index].portrait,),),
                    title: new Text(_userDetails[index].name),
                    subtitle: new Text(_userDetails[index].classs),
                    trailing: new CircleAvatar(backgroundImage: new NetworkImage("https://ochd.co.uk/db/puti/Assets/"+_userDetails[index].type,),),
                    onTap: () {
                      Navigator.push(context, new MaterialPageRoute(builder: (context) => DetailPage(_userDetails[index])));},
                  ),
                  margin: const EdgeInsets.all(0.0),
                );
              },
            ),

          ),

我有點難住哈哈

您在搜索或更改過濾器后不斷重置列表的原因是您正在調用 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 系列和類或使用映射而不是字符串。 如果您覺得字符串更適合具有與過濾器數量相等的字符串,即將 selectedText 轉換為 Map。 由於您使用的是 DropdownMenu,我的假設是您只需要每個過濾器中的一個值

///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){
}

您可以找到更有效的方法。 你不需要我兩次調用 setstate 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM