BaseAdapterの最適化


このセクションの概要:

前のセクションでは、ListView の使用方法と単純な BaseAdapter のカスタマイズ方法を学びました。 getCount() と getView() という 2 つの重要なメソッドがわかります。getView はインターフェイス上の列の数だけ呼び出されます。 この時点で、ビューが新しくインフレートされるたびに、XML を解析する必要があることがわかります。 もちろん、数十または数百の列を含むリストには問題はありませんが、列が増えたり、レイアウトがより複雑になったりした場合はどうなるでしょうか。 したがって、ListView の最適化を学ぶことは非常に重要です。このセクションでは、BaseAdapter の最適化を目的としています。 2 つの最適化ポイントは次のとおりです。 ViewHolder を使用すると、毎回 ViewById を見つける必要がなく、コンポーネントを再利用できます。コードを通してそれを体験してみましょう。


1. ConvertView を再利用します:

上で述べたように、インターフェイス上にアイテムがいくつあるか、その後 getView メソッドが何回呼び出されますか? 前のセクションで書いた getView() コードを見てみましょう:

@Override
public View getView(int Position, View ConvertView, ViewGroupparent) {
ConvertView = LayoutInflater.from(mContext).inflate( R.layout.item_list_animal,parent,false);
ImageView img_icon = (ImageView) ConvertView.findViewById(R.id.img_icon);
TextView txt_aName = (TextView) ConvertView.findViewById(R.id.txt_aName);
TextView txt_aSpeak = (TextView) ConvertView.findViewById(R.id.txt_aSpeak);

img_icon.setBackgroundResource(mData.get(position).getaIcon());
txt_aName.setText(mData.get(position).getaName());
txt_aSpeak.setText(mData.get(position).getaSpeak());
return ConvertView;
}

はい、inflate() は毎回 XML をロードする必要があります。実際、この ConvertView は、私たちが利用できるようにシステムによって提供されるビューです。 オブジェクトをキャッシュしてから、最適化されたコードを変更します:

@Override
public View getView(int Position, View ConvertView, ViewGroupparent) {

if(convertView == null){
ConvertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
}

ImageView img_icon = (ImageView) ConvertView.findViewById(R.id.img_icon);
TextView txt_aName = (TextView) ConvertView。 findViewById(R.id.txt_aName);
TextView txt_aSpeak = (TextView) ConvertView.findViewById(R.id.txt_aSpeak);

img_icon.setBackgroundResource(mData.get(position).getaIcon());
tx t_aName. (mData.get(position).getaName());
txt_aSpeak.setText(mData.get(position).getaSpeak());
return ConvertView;
}

2. ViewHolder はコンポーネントを再利用します

getView() が複数回呼び出されるので、findViewById を複数回呼び出す必要があり、ListView の項目も 通常、レイアウトは同じです。ViewHolder クラスを独自に定義することで、この部分を最適化できます。 パフォーマンスの最適化を実行します。変更されたコードは次のとおりです。

@Override
public View getView(int Position, View ConvertView, ViewGroupparent) {
ViewHolderholder = null;
if(convertView == null){
ConvertView = LayoutInflater .from( mContext ).inflate(R.layout.item_list_animal,parent,false);
Holder = new ViewHolder();
Holder.img_icon = (ImageView) ConvertView.findViewById(R.id.img_icon);
Holder.txt_aName = ( TextView ) ConvertView.findViewById(R.id.txt_aName);
Holder.txt_aSpeak = (TextView) ConvertView.findViewById(R.id.txt_aSpeak);
ConvertView.setTag(holder); // ホルダーを ConvertView に保存します
}else{
Holder = (ViewHolder) ConvertView.getTag();
}
holder.img_icon.setBackgroundResource(mData.get(position).getaIcon());
holder.txt_aName.setText(mData.get(position).getaName() ) ;
holder.txt_aSpeak.setText(mData.get(position).getaSpeak());
return ConvertView;
}

静的クラス ViewHolder{
ImageView img_icon;
TextView txt_aName;
TextView txt_aSpeak;
}

はい、とても簡単です。今後はこのテンプレートに従って BaseAdapter を作成するだけです (笑)。これにより ViewHolder が変更されます。 static は、static として定義されているかどうかに関係なく、複数の場所で使用するために static が追加されます。 Holder を使用する場合、クラスをロードする必要があるのは 1 回だけです。1 回だけ使用する場合は、追加するかどうかは関係ありません。 ——ベリアル(B神)の原文~


このセクションの概要:

さて、BaseAdapterの最適化はおそらく上の2つで、非常に単純で、ConvertViewとカスタムViewHolderを再利用しています。 findViewById() の呼び出し数を減らしてください~BaseAdapter の最適化について他にご提案がございましたら、お気軽にご提案ください、ありがとうございます~