2017-07-07 1 views
0

Ich versuche gerade, ein SearchView zu implementieren, aber die angezeigten Suchergebnisse ändern sich nur für die erste Suche, alles andere, das ich in SearchView eingib, wird ignoriert.Wie wird nach einer Liste von Objekten gesucht, die in einem RecyclerView angezeigt werden?

Hier ist mein Code für die Suche in meinem 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 nach jeder Textänderung aufgerufen wird, aber das Suchergebnis wird nur einmal gezeigt. Bei der Eingabe von a und Enter zeigt der RecyclerView aw und aa (ist es normal, um Enter für onQueryTextChange zu starten?), Aber wenn ich dann aa eingeben, bleiben die angezeigten Elemente gleich.

Antwort

1

Ich denke, Ihre Implementierung ist nicht korrekt. Sie müssen die Eingabetaste nicht für das Suchergebnis drücken. Zur Implementierung können Sie eine intakte Kopie Ihrer Array-Liste beibehalten. Erstellen Sie dann eine andere temporäre Liste, wenn der Abfragetext geändert wird. Wenn Sie also filtern, durchsuchen Sie die tatsächliche Liste und nicht die gefilterte Liste.

1.pass Suchbegriff in die Liste Adapter

public boolean onQueryTextChange(String newText) { 

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

2. In Adapter implementieren Filterbare und Überschreibung Methode

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

    return frameFilter; 
} 

3. Filtering Klasse so etwas wie das sein kann: 'categoryMain' ist meine intakte Liste und "categoryTemp" ist meine temporäre Liste

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

Vielen Dank für Ihre Hilfe. Ihre Lösung funktioniert für mich, wenn ich 'filterResults.values ​​= categoriesMain.clone();' durch 'filterResults.values ​​= categoriesMain' ersetze. – sininen

Verwandte Themen