2017-07-10 16 views
0

私は、リストビューのリスト項目を、textwatcherを使用してファイル名に基づいてフィルタリングすることができました。しかし、これにより、実行時間が長くなり、forループの使用やファイルリストをたどる凍結フレームが発生するかどうかはわかりません。リストビューの検索を高速化する

リストビューでの検索のための私のコード:

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 

     } 
    }); 

このループのためには、リスト内を横断し、大きすぎるリストのための動的な検索が遅いことができます。これをより速くする方法はありますか?

私はコメントからの提案の後にバイナリ検索を試みましたが、実際にはアプリケーションがフリーズしていますので、実装にスポットがあるかどうか分かりません。また、リスト項目には、それだけでなく:

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

あなたはこのようにあなたが代わりに '' O(n)の 'の検索の' O(ログn)を持っている...バイナリ検索を行うことができます。 –

+0

@FallaCoulibaly実際には、1つのアイテムを検索する必要はありませんが、リストアイテムにも名前の一部として検索されたテキストが含まれている場合は、同様にリストしています。だから私はバイナリ検索を試みましたが、私の実装にスポットがあるかどうかわかりません。バイナリ検索コードも追加していますが、ほとんどの開発者がAPI 9以降の互換性を持った検索に使用する方法が必要でした。 –

+0

検索条件が "contains"の場合は、LIKEを使用してクエリを実行するようなものです。リストのすべてのレコードを順次スイープするのと同じです。ほとんどの場合、リストを分割して別のスレッドで別々の検索を実行できます。 – Juan

答えて

0

あなたはメモリのために気にしないならば、あなたがリストとして文字列のリストにあなたのflLst.get(i).getName().toLowerCase()をキャッシュすることができます使用していますがが変更されます。キャッシュとリストアイテムの間には1つの対応があるため、キャッシュの検索を実行し、flLst.からアイテムを取得します。より多くの検索が実行されるほどパフォーマンスが向上します。あなたは、あなたのリストがソートされたままにすると

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

このタイプのキャッシングに慣れていないので、あなたのメソッドをいくつかのコードでサポートできますか? –

関連する問題