我有车辆的列表视图,例如汽车名称,汽车的一些细节。我想找一辆名字的汽车。
我使用Android微调器按照当前状态(运行,停止......)过滤汽车
然后,我在Spinner旁边的搜索框中输入(使用editetext)汽车的名称。它应该在Spinner中过滤带有状态选择的汽车。
我知道如何单独进行,而不是一起进行。如何将微调器滤镜和搜索滤镜组合在一起?真的很感激帮助!
CarlistFragment1 CarListFragment2
Car(Model)创建listview时,我有正常的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 :(得分:0)
我注意到的第一个问题是,您使用过滤结果覆盖了存储在carList
中的原始汽车列表。这意味着当过滤器清除后,您将无法恢复它们。
如果您为原始数据集保留一个列表,并为您将要显示的数据另一个列表,您可能会发现它更容易。最初这些都是一样的。然后在performFilter
中,您可以从完整列表中重新创建包含所需汽车的显示列表。
对于您的实际问题,它看起来不像Filter
类可以处理多个约束类型。如果您已开始使用它,则每次调用performFilter
时,您都需要使用过滤器进行两种类型的过滤。您可以在适配器上创建自己的方法,既可以从微调器中获取状态过滤器,也可以从搜索框中获取文本过滤器,并使用特殊字符(如|
)加入它们。例如:
lost_gps|mysearch
然后用performFilter()
方法将它们分开。
另一点是,如果状态未知,performFilter
中的switch语句实际上只显示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);
}
}
然后在你的Filter类
中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
中的所有车辆。