ListViewスペースが使いにくい理由は、最適化できる詳細がたくさんあるため、運用効率が非常に重要なポイントです。現在、FruitAdapterのgetView()メソッドでは、レイアウトが毎回リロードされるため、ListViewの運用効率は非常に低くなっています。ListViewがすばやくスクロールすると、パフォーマンスのボトルネックになります。
よく見ると、getView()メソッドにconvertViewパラメーターがあることがわかります。このパラメーターは、後で再利用できるように、以前にロードされたレイアウトをキャッシュするために使用されます。
ご覧のとおり、getView()メソッドで判断を下しました。convertViewがnullの場合は、LayoutInflaterを使用してレイアウトをロードします。nullでない場合は、cnvertViewを直接再利用します。これにより、ListViewの操作効率が大幅に向上し、すばやくスクロールしたときのパフォーマンスも向上します。
ただし、現時点では、コードを最適化することはできます。レイアウトをロードするために繰り返されることはなくなりますが、ビューのfindViewById()メソッドは、コントロールのインスタンスを取得するためにgetView()メソッドで毎回呼び出されます。 。
ViewHolderを使用して、パフォーマンスのこの部分を最適化し、FruitAdapterのコードを次のように変更できます。
package net.nyist.lenovo.listviewtest;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class FruitAdapter extends ArrayAdapter<Fruit>{
private int resourceId;
public FruitAdapter(Context context, int textViewResourceId, List<Fruit>objects){
super(context,textViewResourceId,objects);
resourceId = textViewResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position);//获取当前项的Fruit实例
View view;
ViewHolder viewHolder;
if (convertView==null){
view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
viewHolder = new ViewHolder();
viewHolder.fruitImage = (ImageView)view.findViewById(R.id.fruit_image);
viewHolder.fruitName = (TextView)view.findViewById(R.id.fruit_name);
view.setTag(viewHolder);//将ViewHolder存储在View中。
}else {
view = convertView;
}
ImageView fruitImage = (ImageView)view.findViewById(R.id.fruit_image);
TextView fruitName = (TextView)view.findViewById(R.id.fruit_name);
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());
return view;
}
class ViewHolder{
ImageView fruitImage;
TextView fruitName;
}
}
コントロールのインスタンスをキャッシュするために使用される新しい内部クラスViewHolderを追加しました。convertViewがnullの場合、ViewHolderオブジェクトを作成し、コントロールインスタンスをViewHolderに格納してから、ViewのsetTag()メソッドを呼び出してViewHolderオブジェクトをViewに格納します。convertViewがnullでない場合は、ViewのgetTag()メソッドを呼び出します。 ViewHolderを再び出力します。このように、すべてのコントロールインスタンスはViewHolderにキャッシュされ、毎回findViewById()メソッドを介してコントロールインスタンスを取得する必要はありません。
これらの2つの最適化ステップの後、ListViewの効率はすでに非常に良好です。