2017-10-16 129 views
0

我有一個列表視圖與汽車,如汽車名稱,汽車的一些細節。我想通過它的名字找到一輛汽車。使用微調器過濾器列表視圖然後searchbox(edittext)

  1. 我用它的當前狀態(運行,停止,...)的Android微調

  2. 然後過濾車,我在搜索框中(使用editetext)型微調器旁邊汽車的名稱。它應該在Spinner中選擇狀態來過濾汽車。

我知道如何分開做,但不能在一起。我怎樣才能將微調濾鏡和搜索濾鏡結合在一起?真的很感謝幫助!

CarlistFragment1CarListFragment2

車(模型)創建一個列表視圖時,我有setter和getter方法爲正常。

CarAdapter代碼:

//This car list adapter class provides data to list view 
public class CarListAdapter extends BaseAdapter implements Filterable{ 

    private Context context; 
    private LayoutInflater inflater; 
    private List<Car> carList; // Original Data 
    private List<Car> carListSpinnerFiltered; // spinner filtered data 
    //private List<Car> carListSearchFiltered; // search filtered data 
    private ValueFilter valueFilter; 
    private ImageLoader imageLoader = AppController.getInstance().getImageLoader(); 

    public CarListAdapter(Context context, List<Car> carList) { 
     this.context = context; 
     this.carList = carList; 
     this.carListSpinnerFiltered = carList; 
     //this.carListSearchFiltered = carList; 
    } 

    @Override 
    public int getCount() { 
     return carList.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return carList.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
//  return position; 
     return carList.indexOf(getItem(position)); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     if (inflater == null) 
      inflater = (LayoutInflater) context 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     if (convertView == null) 
      convertView = inflater.inflate(R.layout.list_row_carlist, null); 

     if (imageLoader == null) 
      imageLoader = AppController.getInstance().getImageLoader(); 
     NetworkImageView thumbNail = (NetworkImageView) convertView 
       .findViewById(R.id.car_image); 

     TextView devname = (TextView) convertView.findViewById(R.id.devname); 
     TextView location = (TextView) convertView.findViewById(R.id.location); 
     TextView status = (TextView) convertView.findViewById(R.id.status); 
     TextView speed = (TextView) convertView.findViewById(R.id.speed); 

     // getting vehicle data for the row 
     final Car c = carList.get(position); 

     // thumbnail image 
//  thumbNail.setImageUrl(c.getImageURL(), imageLoader); 

     // device name 
     devname.setText(c.getDevname()); 

     // location 
     if (c.getLocation().equals("")) { 
      location.setText(String.valueOf("Location unknown")); 
     } else { 
      location.setText(String.valueOf(c.getLocation())); 
     } 

     // status 
      switch (c.getStatus()) { 
       case "run": 
        status.setText(String.valueOf(statusRun)); 
        status.setTextColor(ContextCompat.getColor(context.getApplicationContext(), R.color.colorCarRun)); 
        break; 

       case "stop": 
        status.setText(String.valueOf(statusStop)); 
        status.setTextColor(ContextCompat.getColor(context.getApplicationContext(), R.color.colorCarStop)); 
        break; 

       case "lost_gprs": 
        status.setText(String.valueOf(statusLostGprs)); 
        status.setTextColor(ContextCompat.getColor(context.getApplicationContext(), R.color.colorBlack)); 
        break; 

       case "lost_gps": 
        status.setText(String.valueOf(statusLostGps)); 
        status.setTextColor(ContextCompat.getColor(context.getApplicationContext(), R.color.colorffbf00)); 
        break; 

       case "expired": 
        status.setText(String.valueOf("Expired")); 
        status.setTextColor(ContextCompat.getColor(context.getApplicationContext(), R.color.colorBlue)); 
        break; 
      } 

     // speed 
     speed.setText(String.valueOf(c.getSpeed())); 

     return convertView; 
    } 

    @Override 
    public Filter getFilter() { 
     if (valueFilter == null) { 
      valueFilter = new ValueFilter(); 
     } 
     return valueFilter; 
    } 

    private class ValueFilter extends Filter { 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults results = new FilterResults(); 


      // Search Field 
//   if (constraint != null && constraint.length() > 0) { 
//    ArrayList<Car> filterList = new ArrayList<>(); 
// 
//    for (int i = 0; i < carListSearchFiltered.size(); i++) { 
// 
//     String devname = carListSearchFiltered.get(i).getDevname().toUpperCase(); 
//     String inputString = constraint.toString().toUpperCase(); 
// 
//     if (devname.contains(inputString)) { 
//      Car car = new Car(); 
//      car.setDevname(carListSearchFiltered.get(i).getDevname()); 
//      car.setLocation(carListSearchFiltered.get(i).getLocation()); 
//      car.setStatus(carListSearchFiltered.get(i).getStatus()); 
//      car.setSpeed(carListSearchFiltered.get(i).getSpeed()); 
//      car.setDevid(carListSearchFiltered.get(i).getDevid()); 
//      filterList.add(car); 
//     } 
// 
// 
//    } // end for loop 
// 
//    results.count = filterList.size(); 
//    results.values = filterList; 
// 
//   } else { 
//    results.count = carListSearchFiltered.size(); 
//    results.values = carListSearchFiltered; 
//   } 



      // Spinner Filter 
      String inputStatus = constraint.toString(); 

      if (!inputStatus.equals("All")) { 

       ArrayList<Car> spinnerList = new ArrayList<>(); 

       for (int i = 0; i < carListSpinnerFiltered.size(); i++){ 
        String carStatus = carListSpinnerFiltered.get(i).getStatus(); 

        switch (carStatus){ 
         case "run": 
          carStatus = "run"; 
          break; 

         case "stop": 
          carStatus = "stop"; 
          break; 

         case "lost_gprs": 
          carStatus = "lost_gprs"; 
          break; 

         case "lost_gps": 
          carStatus = "lost_gps"; 
          break; 

         default: 
          Toast.makeText(context, "status unknown", Toast.LENGTH_SHORT).show(); 
          break; 

        } // end switch 

        if (carStatus.equals(inputStatus)) { 

         Car car = new Car(); 
         car.setDevname(carListSpinnerFiltered.get(i).getDevname()); 
         car.setLocation(carListSpinnerFiltered.get(i).getLocation()); 
         car.setStatus(carListSpinnerFiltered.get(i).getStatus()); 
         car.setSpeed(carListSpinnerFiltered.get(i).getSpeed()); 
         car.setDevid(carListSpinnerFiltered.get(i).getDevid()); 
         spinnerList.add(car); 

        } 

       } // end for loop 

       results.count = spinnerList.size(); 
       results.values = spinnerList; 

      } else { 

       results.count = carListSpinnerFiltered.size(); 
       results.values = carListSpinnerFiltered; 
      } 

      return results; 
     } 

     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      carList = (List<Car>) results.values; 
      notifyDataSetChanged(); 
     } 

    } // end class 

} 

回答

0

的第一個問題,我注意到的是,你會覆蓋你原車的名單,存儲在carList,與過濾結果。這意味着當過濾器被清除時,您將無法恢復它們。

如果您保留原始數據集的一個列表以及您將顯示的另一個數據列表,可能會更容易。最初這些將是相同的。然後在performFilter中,您可以從完整列表中重新創建您想要的汽車的顯示列表。

對於您的實際問題,它看起來不像Filter類可以處理多個約束類型。如果您開始使用它,則每次調用performFilter時都需要使用過濾器來執行兩種類型的過濾。你可以在你的適配器上創建你自己的方法,從你的微調器中取得一個狀態過濾器,並從你的搜索框中取出一個文本過濾器,並用一個特殊字符(如|)加入它們。例如:

lost_gps|mysearch

然後在performFilter()方法將它們分開。

另一點是,如果狀態未知,performFilter中的切換語句實際上只是顯示Toast。沒有一項任務可以做任何事情,它可以替換爲if聲明,您可以在這個聲明中針對每種狀態進行測試,或者如果狀態是在預先製作的HashSet對象中,然後您可以只使用Set.contains(),則更好。

更新:

要割肉出局的想法多了,你的適配器,你會碰到這樣的

class Adapter ... { 
    private String mStatusFilter = ""; 
    private String mSearchFilter = ""; 

    private void setStatusFilter(String statusFilter) { 
     mStatusFilter = statusFilter; 
     getFilter().filter(mStatusFilter + "|" + mSearchFilter); 
    } 

    private void setSearchFilter(String searchFilter) { 
     mSearchFilter = searchFilter; 
     getFilter().filter(mStatusFilter + "|" + mSearchFilter); 
    } 
} 

然後在您的過濾器類

performFiltering(CharSequence constraint) { 
    displayedCarList.clear(); 
    String statusFilter = constraint.split("|")[0] 
    String searchFilter = constraint.split("|")[1] 
    for(Car car: carList) { 
     // Does it match the status? (if filter not set, default to yes) 
     boolean statusMatch = TextUtils.isEmpty(statusFilter) || 
      car.status.equals(statusFilter); 
     // Does it match the name? (if filter not set, default to yes) 
     boolean searchMatch = TextUtils.isEmpty(searchFilter) || 
      car.name.contains(searchFilter); 
     if(statusMatch && searchMatch) { 
      displayedCarList.add(car) 
     } 
    } 
    ... 
} 

適配器將只顯示所有在displayedCarList的汽車。

+0

謝謝你的評論,但我還是不太瞭解它。我無法同時實現兩個過濾器。微調器將顯示當前所選狀態的所有汽車。只有這樣用戶纔想要在微調器結果中過濾特定的汽車。執行過濾器()只有一個約束。我怎樣才能過濾listview與多個約束分開?這很難。我無法解決這個人! –

+0

我在代碼中充實了我的想法,這有幫助嗎?你能解釋一下你不明白的部分嗎? – Xiao

+0

我仍在嘗試 –