2017-07-10 6 views
0

Ich konnte Listenelemente in einer Listview basierend auf dem Dateinamen mit Textwatcher filtern. Ich bin mir jedoch nicht sicher, ob dies zu einer längeren Ausführungszeit und eingefrorenen Frames führt, wenn die for-Schleifen verwendet und durch die Dateiliste durchlaufen werden.Machen Sie Listview Suche schneller

Mein Code für in Listenansicht Suche:

edsearch.addTextChangedListener(new TextWatcher() { 

     @Override 
     public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { 

      List<File> ccpt = new ArrayList<File>(); 
      String text = edsearch.getText().toString().toLowerCase(); 

      for(int i=0;i<flLst.size();i++){ 
       if(flLst.get(i).getName().toLowerCase().contains(text)){ 
        ccpt.add(flLst.get(i)); 
       } 

      } 

      FlAdapter mAdapterx = new FlAdapter(ListFiles.this, R.layout.fl_list_item, ccpt); 
      mListView.setAdapter(mAdapterx); 
     } 

     @Override 
     public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, 
             int arg3) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void afterTextChanged(Editable arg0) { 
      // TODO Auto-generated method stub 

     } 
    }); 

quert durch die Liste Dieses for-Schleife und kann die dynamische Suche nach einer Liste langsam machen, die zu groß ist. Gibt es eine Möglichkeit, dies schneller zu machen?

Ich versuchte binäre Suche nach einem Vorschlag aus Kommentaren, aber es friert tatsächlich die App, so dass ich nicht sicher bin, ob meine Implementierung genau richtig ist, auch wenn ein Listenelement auch den gesuchten Text als Teil seines Namens enthält wie gut, dass:

public List<File> binarySearch(ArrayList<File> array, String value) 
{ 
    int start = 0; 
    int end = array.size() - 1; 

    ArrayList<File> temps = new ArrayList<File>(); 

    while (start <= end) 
    { 
     int middle = start + (end - start)/2; 
     if (array.get(middle).getName().contains(value)) { 
      temps.add(array.get(middle)); 
      // return true; 
     } 
     else if (array.get(middle).getName().compareTo(value)>0) 
     { 
      end = middle - 1; 
     } 
     else start = middle + 1; 
    } 
    return temps; 
} 
+0

Sie können eine binäre Suche tun, wenn Ihre Liste sortiert halten ... So Sie 'O haben (log n)' statt 'O (n)' für die Suche. –

+0

@FallaCoulibaly Eigentlich muss ich nicht nur nach einem Element suchen, sondern wenn ein Listenelement auch den gesuchten Text als Teil seines Namens enthält, listet ich das ebenfalls auf. Also habe ich die binäre Suche versucht, aber ich bin mir nicht sicher, ob meine Implementierung genau richtig ist. Ich füge auch meinen binären Suchcode hinzu, aber ich wollte eine Methode, die die meisten Entwickler für die Suche mit Kompatibilität seit API 9 verwenden. –

+0

Wenn das Suchkriterium "enthält" ist wie eine Abfrage mit einem LIKE Sie benötigen einen vollständigen Scan, der ist das gleiche wie alle Datensätze der Liste nacheinander zu durchsuchen. Sie können die Liste höchstens in Teile aufteilen und separate Suchen auf verschiedenen Threads ausführen. – Juan

Antwort

0

Wenn Sie Speicher nicht egal verwendet, dann können Sie Ihre flLst.get(i).getName().toLowerCase() auf einer Liste von String als Liste Cache ist geändert. Da es eine einzige Entsprechung zwischen Cache und Listenelementen gibt, führen Sie Suchvorgänge im Cache durch und holen Sie ein Element von flLst.. Es wird eine bessere Leistung erbringen, da mehr und mehr Suchen durchgeführt werden.

EDIT

flLst = getYourListLigic(); 
ArrayList <String> cache = new ArrayList <>(); 
for(int i=0;i<flLst.size();i++){ 
    cache.add (flLst.get(i).getName().toLowerCase()); 

edsearch.addTextChangedListener(new TextWatcher() { 

    @Override 
    public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { 

     List<File> ccpt = new ArrayList<File>(); 
     String text = edsearch.getText().toString().toLowerCase(); 

     for(int i=0;i<flLst.size();i++){ 
      if(cache.get(i).contains(text)){ 
       ccpt.add(flLst.get(i)); 
      } 

     } 

     FlAdapter mAdapterx = new FlAdapter(ListFiles.this, R.layout.fl_list_item, ccpt); 
     mListView.setAdapter(mAdapterx); 
    } 

    @Override 
    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, 
            int arg3) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void afterTextChanged(Editable arg0) { 
     // TODO Auto-generated method stub 

    } 
}); 
+0

Können Sie Ihre Methode mit Code unterstützen, da ich mit dieser Art von Caching nicht vertraut bin? –