2017-07-07 1 views
0

J'essaie actuellement d'implémenter un SearchView, mais les résultats de recherche affichés ne changent que pour la première recherche, tout ce que j'entre dans SearchView est ignoré.Comment rechercher une liste d'objets affichés dans un RecyclerView?

Voici mon code pour la recherche dans mon MainActivity.java:

testList = Arrays.asList(new TestItem("aw"), new TestItem("aa"), new TestItem("w")); 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.test_menu, menu); 

    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); 
    searchView.setOnQueryTextListener(this); 
    return super.onCreateOptionsMenu(menu); 
} 

@Override 
public boolean onQueryTextChange(String newText) { 
    List<TestItem> result = new ArrayList<>(); 
    for(TestItem t: testList) { 
     if(t.getName().contains(newText) { 
      result.add(t); 
     } 
    } 
    adapter.changeList(result); 
    return true; 
} 

adapter.changeList:

public void changeList(List<TestItem> newList) { 
    this.list = new ArrayList<>(newList); 
} 

onQueryTextChange est appelée après chaque changement de texte, mais le résultat de recherche est présentée une seule fois. Lorsque vous entrez a et Enter le RecyclerView affiche aw et aa (est-il normal d'avoir à appuyer sur Entrée pour onQueryTextChange pour commencer?), Mais quand j'entre alors aa les articles affichés restent les mêmes.

Répondre

1

Je pense que votre implémentation n'est pas correcte. Vous n'avez pas besoin d'appuyer sur Entrée pour obtenir le résultat de la recherche. Pour l'implémentation, vous pouvez conserver une copie intacte de votre liste de tableaux. Ensuite, créez un autre formulaire de liste temporaire lorsque le texte de la requête est modifié. Ainsi, lorsque vous filtrez, vous recherchez la liste actuelle et non la liste filtrée.

1.pass mot-clé de recherche à l'adaptateur liste

public boolean onQueryTextChange(String newText) { 

    adapter.getFilter().filter(newText); 
    return true; 
} 

2. Dans l'adaptateur et mettre en œuvre la méthode filtrables override

@Override 
public Filter getFilter() { 
    if (frameFilter == null) { 
     frameFilter = new FrameFilter(); 
    } 

    return frameFilter; 
} 

3. classe de filtrage peut être quelque chose comme ceci: 'categoryMain' est ma liste intacte et 'categoryTemp' est ma liste temporaire

private class FrameFilter extends Filter { 

    @Override 
    protected FilterResults performFiltering(CharSequence constraint) { 

     FilterResults filterResults = new FilterResults(); 
     if (constraint != null && constraint.length() > 0) { 
      ArrayList<Category> tempList = new ArrayList<>(); 

      // search content in friend list 
      Log.i("key",constraint.toString()); 
      for (Category category : categoriesMain) { 
       if (category.getCategory_name().toLowerCase().contains(constraint.toString().toLowerCase())) { 
        tempList.add(category); 
       } 
      } 
      filterResults.count = tempList.size(); 
      filterResults.values = tempList; 
     } else { 

      filterResults.count = categoriesMain.size(); 
      filterResults.values = categoriesMain.clone(); 
     } 
     return filterResults; 
    } 

    /** 
    * Notify about filtered list to ui 
    * 
    * @param constraint text 
    * @param results filtered result 
    */ 
    @SuppressWarnings("unchecked") 
    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 

     categoriesTemp = (ArrayList<Category>) results.values; 
     notifyDataSetChanged(); 
    } 
} 
+0

Merci beaucoup pour votre aide. Votre solution fonctionne pour moi si je remplace 'filterResults.values ​​= categoriesMain.clone();' avec 'filterResults.values ​​= categoriesMain'. – sininen