2011-06-27 4 views
28

私はAndroidの初心者ですが、カスタムリストビューをフィルタリングしようとしましたが、何とか働きました。私が持っている唯一の問題は、すべての値( "オリジナル" ArrayList)を保持していたArrayListは、すべてのフィルタリングで項目の値が低くなります。私はこれを説明することはできませんが、私はあなたが何とか私を助けることができると思った。ListViewのカスタムフィルタリングArrayAdapter

public class PkmnAdapter extends ArrayAdapter<Pkmn> { 

private ArrayList<Pkmn> original; 
private ArrayList<Pkmn> fitems; 
private Filter filter; 

public PkmnAdapter(Context context, int textViewResourceId, ArrayList<Pkmn> items) { 
     super(context, textViewResourceId, items); 
     this.original = items;//new ArrayList<Pkmn>(); 
     this.fitems = items;//new ArrayList<Pkmn>(); 
} 

@Override 
public void add(Pkmn item){ 
    original.add(item); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
     View v = convertView; 
     if (v == null) { 
      LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.row, null); 
     } 
     Pkmn pkmn = original.get(position); 
     if (pkmn != null) { 
       TextView tt = (TextView) v.findViewById(R.id.RlabPName); 
       TextView dex = (TextView)v.findViewById(R.id.RlabDex); 
       ImageView img = (ImageView)v.findViewById(R.id.RimgPkmn); 

       if (tt != null) { tt.setText(pkmn.getName()); } 
       if (dex != null){ dex.setText(CalcDex(pkmn.getId())); } 
       if (img != null){ 
        int resId = getContext().getResources().getIdentifier("dex" + pkmn.getId(), "drawable", "com.compileguy.pokebwteam"); 
        img.setImageResource(resId); 
       } 
     } 
     return v; 
} 

@Override 
public Filter getFilter() 
{ 
    if (filter == null) 
     filter = new PkmnNameFilter(); 

    return filter; 
} 

private class PkmnNameFilter extends Filter 
{ 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) 
     { 
      FilterResults results = new FilterResults(); 
      String prefix = constraint.toString().toLowerCase(); 

      if (prefix == null || prefix.length() == 0) 
      { 
       ArrayList<Pkmn> list = new ArrayList<Pkmn>(original); 
       results.values = list; 
       results.count = list.size(); 
      } 
      else 
      { 
       final ArrayList<Pkmn> list = original; 

       int count = list.size(); 
       final ArrayList<Pkmn> nlist = new ArrayList<Pkmn>(count); 

       for (int i=0; i<count; i++) 
       { 
        final Pkmn pkmn = list.get(i); 
        final String value = pkmn.getName().toLowerCase(); 

        if (value.startsWith(prefix)) 
        { 
         nlist.add(pkmn); 
        } 
       } 
       results.values = nlist; 
       results.count = nlist.size(); 
      } 
      return results; 
     } 

     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      fitems = (ArrayList<Pkmn>)results.values; 
      clear(); 
      int count = fitems.size(); 
      for (int i=0; i<count; i++) 
      { 
       Pkmn pkmn = (Pkmn)fitems.get(i); 
       add(pkmn); 
      } 

      if (fitems.size() > 0) 
       notifyDataSetChanged(); 
      else 
       notifyDataSetInvalidated(); 
     } 

    } 


private String CalcDex(int id){ 
    String s = String.valueOf(id); 
    if (s.length() == 1) 
     s = "00"+s; 
    else if (s.length() == 2) 
     s = "0"+s; 
    return '#'+s; 
} 

}

注:リストビューは正しく項目を示しているが、exapleのために、私は(フィルタリングをトリガー)エディットボックス内の文字を削除するときは、このとにかくここ

カスタムArrayAdaptorです問題が始まる場所です。

--- EDIT ---

@Janusz:あなたの答えに感謝。それが私の問題を解決しました。誰もが同じ問題を持っている場合、彼らはこの1つを試みることができるので、ここで

は、私の作品のソースコードです:

private ArrayList<Pkmn> original; 
private ArrayList<Pkmn> fitems; 
private Filter filter; 

public PkmnAdapter(Context context, int textViewResourceId, ArrayList<Pkmn> items) { 
     super(context, textViewResourceId, items); 
     this.original = new ArrayList<Pkmn>(items); 
     this.fitems = new ArrayList<Pkmn>(items); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
     View v = convertView; 
     if (v == null) { 
      LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.row, null); 
     } 
     Pkmn pkmn = fitems.get(position); 
     if (pkmn != null) { 
       TextView tt = (TextView) v.findViewById(R.id.RlabPName); 
       TextView dex = (TextView)v.findViewById(R.id.RlabDex); 
       ImageView img = (ImageView)v.findViewById(R.id.RimgPkmn); 

       if (tt != null) { tt.setText(pkmn.getName()); } 
       if (dex != null){ dex.setText(CalcDex(pkmn.getId())); } 
       if (img != null){ 
        int resId = getContext().getResources().getIdentifier("dex" + pkmn.getId(), "drawable", "com.compileguy.pokebwteam"); 
        img.setImageResource(resId); 
       } 
     } 
     return v; 
} 

@Override 
public Filter getFilter() 
{ 
    if (filter == null) 
     filter = new PkmnNameFilter(); 

    return filter; 
} 

private class PkmnNameFilter extends Filter 
{ 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) 
     { 
      FilterResults results = new FilterResults(); 
      String prefix = constraint.toString().toLowerCase(); 

      if (prefix == null || prefix.length() == 0) 
      { 
       ArrayList<Pkmn> list = new ArrayList<Pkmn>(original); 
       results.values = list; 
       results.count = list.size(); 
      } 
      else 
      { 
       final ArrayList<Pkmn> list = new ArrayList<Pkmn>(original); 
       final ArrayList<Pkmn> nlist = new ArrayList<Pkmn>(); 
       int count = list.size(); 

       for (int i=0; i<count; i++) 
       { 
        final Pkmn pkmn = list.get(i); 
        final String value = pkmn.getName().toLowerCase(); 

        if (value.startsWith(prefix)) 
        { 
         nlist.add(pkmn); 
        } 
       } 
       results.values = nlist; 
       results.count = nlist.size(); 
      } 
      return results; 
     } 

     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      fitems = (ArrayList<Pkmn>)results.values; 

      clear(); 
      int count = fitems.size(); 
      for (int i=0; i<count; i++) 
      { 
       Pkmn pkmn = (Pkmn)fitems.get(i); 
       add(pkmn); 
      } 
     } 

    } 
} 
+0

')(クリア' の仕事と 'を追加()' 関数は何ですか。 –

+0

@compileGuy、 "Pkmn"はどういう意味ですか?私はこの例を実行することはできません。コードを完全にアップロードできますか? –

+0

優れた実装@compileguy、 アダプタで機能を追加してクリアすると、それらを上書きする必要はありません。 pkmnはデータ値をリストに保持するモデルクラスです – Naruto

答えて

16

あなたの問題は、この線です:

this.original = items; 
this.fitems = items; 

アイテムですListViewで使用するリストを2つの異なる変数に入れても、2つの異なるリストが作成されるわけではありません。リスト項目には2つの異なる名前しか付けられません。

を使用できます。新しいリストを生成する必要があり、このリスト上の変更のみfitemsリストを変更します

this.fitems = new ArrayList(items); 

を。

+0

Janusz、ありがとう、ありがとうございましたlot – Naruto

+0

私のために働いていない、私のリストビューが消えて、再び。 http://stackoverflow.com/questions/20524417/listview-is-blank-while-using-getfilter-function – Si8

+0

@ SiKni8私も同じ結果を得ています。助けてください –

2

フィルタリングする値を返すPkmnクラスにtoString()メソッドを作成するだけで、同じ効果を達成できます。

0

私はArrayAdapterをフィルタリングするために発見された最良の方法は、自分自身のフィルタクラスを作成することです:

private class MyFilter extends Filter 

その関数内でフィルタした後、表示する新しいオブジェクト配列を作成します(あなたが良い実装を見つけることができますclass ArrayAdapterのソースコード)

@Override 
protected FilterResults performFiltering(CharSequence prefix) 

現在、トリックは、この方法にある

@Override 
protected void publishResults(CharSequence constraint, FilterResults results) 
あなたはアレイアダプタを使用するときに3210

あなたははこれを行うことはできません。

myAdapterData = results.values 

を、あなたはスーパーデータからデータを切断するので、あなたはスーパーオリジナルのデータ配列へのご参照を保持するために、この操作を行う必要があります。

data.clear(); 
data.addAll((List<YourType>) results.values); 

、次いで

れるgetFilterを(上書き)

例えば、あなたのアダプタで

、:

@Override 
public Filter getFilter() { 
    if (filter == null) { 
     filter = new MyFilter(); 
    } 
    return filter; 
}