2017-10-16 20 views
0

J'ai une liste avec des voitures telles que le nom de la voiture, certains détails de la voiture. Je voudrais trouver une voiture par son nom.Filtrer liste avec spinner puis searchbox (edittext)

  1. Je filtre les voitures par son état actuel (marche, arrêt, ...) en utilisant spinner Android

  2. Ensuite, je tape dans la zone de recherche (en utilisant editetext) à côté du Spinner de la voiture prénom. Il devrait filtrer la voiture (s) avec le statut choisi dans le fileur.

Je sais comment les faire séparément mais pas ensemble. Comment puis-je combiner à la fois le filtre spinner et le filtre de recherche? Vraiment apprécier l'aide!

CarlistFragment1CarListFragment2

voiture (modèle) Je méthode setter et getter normalement lors de la création d'un listview.

Code 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 

} 

Répondre

0

La première question que je remarque est que vous écrasez votre liste originale des voitures, stockées dans carList, avec les résultats du filtre. Cela signifie que lorsque le filtre est effacé, vous ne serez pas en mesure de les restaurer.

Vous trouverez peut-être plus simple de conserver une liste pour l'ensemble de données d'origine et une autre pour les données que vous allez afficher. Initialement, ceux-ci seront les mêmes. Puis dans performFilter vous pouvez recréer la liste d'affichage avec les voitures que vous voulez dans la liste complète.

Pour votre question actuelle, il ne semble pas que la classe Filter puisse gérer plusieurs types de contraintes. Si vous avez l'intention de l'utiliser, vous aurez besoin de votre filtre pour faire les deux types de filtrage chaque fois que performFilter a été appelée. Vous pouvez créer vos propres méthodes sur votre adaptateur qui prennent à la fois un filtre d'état à partir de votre spinner et un filtre de texte de votre boîte de recherche et les joindre avec un caractère spécial, comme |. Exemple:

lost_gps|mysearch

ensuite les séparer dans la méthode performFilter().

Un autre point est que votre instruction switch dans performFilter affiche en fait simplement un Toast si le statut n'est pas connu. Aucune des affectations ne fait quoi que ce soit, elle pourrait être remplacée par une instruction if où vous testeriez chacun des statuts, ou mieux si les statuts étaient dans un objet préfixé HashSet et que vous pourriez juste utiliser Set.contains().

Mise à jour:

Pour étoffer l'idée plus, dans votre adaptateur que vous auriez quelque chose comme

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); 
    } 
} 

Ensuite, dans la classe de filtre

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) 
     } 
    } 
    ... 
} 

L'adaptateur serait tout simplement afficher tous les voitures au displayedCarList.

+0

Merci pour votre commentaire mais je ne comprends toujours pas beaucoup. Je ne peux pas implémenter les deux filtres en même temps. Le fileur est de montrer toutes les voitures avec le statut sélectionné actuel. Ce n'est qu'alors que l'utilisateur souhaite filtrer une voiture spécifique dans le résultat de la roulette. Le problème est performingFilter() prend seulement une contrainte. Comment puis-je filtrer listview avec plusieurs contraintes séparément? C'est dur. Je ne peux pas résoudre cet homme! –

+0

J'ai étoffé un peu mon idée dans le code, cela aide-t-il? Pouvez-vous expliquer plus quelle partie vous ne comprenez pas? – Xiao

+0

J'essaie toujours –