カスタムリストビューを実装するための簡単なコードスニペットがあります。
私のコードは次のとおりです:
WeatherAdapter.Java:
_public class WeatherAdapter extends ArrayAdapter<weather>{
Context mcontext;
int mlayoutResourceId;
weather mdata[] = null;
View row;
public WeatherAdapter(Context context, int layoutResourceId, weather[] data) {
super(context, layoutResourceId, data);
mlayoutResourceId = layoutResourceId;
mcontext = context;
mdata = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
row = convertView;
WeatherHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ( (Activity) mcontext).getLayoutInflater();
row = inflater.inflate(mlayoutResourceId, parent, false);
holder = new WeatherHolder(row);
row.setTag(holder);
}
else
{
holder = (WeatherHolder)row.getTag();
}
weather w = mdata[position];
holder.txtTitle.setText(w.mtitle);
holder.imgIcon.setImageResource(w.micon);
return row;
}
_
WeatherHolder.Java:
_class WeatherHolder
{
ImageView imgIcon;
TextView txtTitle;
public WeatherHolder(View v){
imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
txtTitle = (TextView)row.findViewById(R.id.txtTitle);
}
}
}
_
SOおよびその他のサイトで多くの回答を目にしてきましたが、リストビューのリサイクルメカニズムを理解しました。
また、viewholderから、子ビューをアダプターに保持できるため、findViewById()
を何度も呼び出す必要がないことも理解しました。つまり、最適化のためです。
しかし、私はsetTag(holder)
およびgetTag()
メソッドの混乱のみを持っています。 この質問から 、複数のオブジェクトでキーと値のペアを作成して、それらに簡単にアクセスできるようにすることがわかった。ただし、ここでそれらが必要な理由はわかりません...なぜなら、複数のホルダーオブジェクトがないからです...ホルダーの変数を毎回変更する必要があるだけです。 setTag
とgetTag
を使用せずにここでコーディングできますか?
誰かがsetTag
とgetTag
が「ここ」で何をするかについてよりよく説明できますか?
tag
は、views
にobject
、integer
、string
など、好きなものを覚えさせるためのメカニズムです。
したがって、ListView
を初めて作成するときは、convertView
はnull
です。したがって、新しいconvertView
を作成し、そのreferences
のobjects
のrow
のすべてをviewHolder
に入れます。次に、viewHolder
をそのconvertView
(setTag)のメモリに保存します。 Android
は、convertView
を受け取り、pool
に入れてrecycle
itに、passes
にもう一度入れます。ただし、そのpool
には十分なconvertViews
がない可能性があるため、新しいconvertView
を再度渡しますnull
。したがって、pool
のAndroid
がいっぱいになるまで、この話が繰り返されます。その後、Android
はプールからconvertView
を受け取り、それをユーザーに渡します。あなたはそれがnull
ではないことに気づくでしょう。そこで、私が初めてあなたに与えたreferences
のオブジェクトはどこにあるのかと尋ねますか? (getTag)なので、それらを取得して好きなように実行できます。
以下の行の詳細
but its pool may not have enough convertViews so it again passes a new convertView thats null
pool
を作成しようとしているとき、Android listView
は空です。したがって、listView
の最初の項目については、表示する必要があるconvertView
を送信します。その後、Android
はそれをpool
に保存するため、pool
にはconvertView
が1つだけ含まれるようになります。作成するlistView
の2番目の項目の場合Androidには実際には1つの要素があり、その要素が最初の項目であり、現在表示されているため、プールを使用できません。別のconvertView
を渡す必要があります。このプロセスは、Android
が現在表示されていないconvertView
内にpool
を見つけて渡すまで繰り返されます。
Androidは、リストをスクロールするときにホルダーを使用して、画面がいっぱいになるまで各行を膨らませます。
別の視点から見てみましょう:
ヘリコプターが「行」であり、ロープは "setTag"であり、以下のcarは "WeatherHolder 「しかし、ヘリコプターのパイロットはその車の中にいて、彼/彼女は "有線リモート"を使用してヘリコプターを制御している人です。
「setTag」であるロープをカットしても、ヘリコプターは飛行しますが、パイロットが地面に落ちているため、パイロットはそれを制御できなくなりました。 (Javaでは、オブジェクトがその参照を失うと、ガベージコレクターがそれを収集してメモリから解放します)。
パイロットが座っている場所でヘリコプターが飛行しようとしているときにロープを車に取り付けたり取り付けなかったりした場合-「ワイヤードリモート」を使用しているため、ヘリコプターのコントロールを失う可能性があります。
私はこの助けを願っています:)。
しかし、なぜここでそれらが必要なのかわかりません...なぜなら、複数のホルダーオブジェクトがないからです
これはあなたが間違っているところです-ビューごとに1つのホルダーがあります(別名表示またはキャッシュされたListViewエントリ)。