关于ViewHolder的终极优化

时间:2022-10-03 14:44:00

传统ViewHolder存在问题举例:

  <pre class="java" name="code">@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = getLayoutInflater().inflate(R.layout.lv_item_publish_image, null);
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
viewHolder.rightSignImage = convertView.findViewById(R.id.rightSignImage);
ViewGroup.LayoutParams lp = viewHolder.imageView.getLayoutParams();
lp.width = lp.height = imageSize;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if (position == getDataCount()) {
ImageLoader.getInstance().cancelDisplayTask(viewHolder.imageView);
viewHolder.imageView.setImageResource(R.drawable.sl_icon_add_photo);
viewHolder.rightSignImage.setVisibility(View.GONE);
viewHolder.rightSignImage.setOnClickListener(null);
} else {
String data = getItem(position);

String uri = null;
if (data.startsWith("http")) {
uri = data;
} else {
uri = Uri.fromFile(new File(data)).toString();
}
ImageLoader.getInstance().displayImage(uri, viewHolder.imageView, option);
viewHolder.rightSignImage.setVisibility(View.VISIBLE);
viewHolder.rightSignImage.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
remove(position);
notifyDataSetChanged();
}
});
}

return convertView;
}

private static final class ViewHolder {
ImageView imageView;
View rightSignImage;
}
}


如上。如果你的项目巨大 ,将会有很多Adapter 每个类是不是都要写一个 viewHolder?是不是很操蛋。为何不精简下呢?
 

Java的重构思想就是要减少重复对不对?如何做?

 

解决办法:单独新建ViewHolder

public class ViewHolder {

private final SparseArray<View> sparseVies;
private View convertView;

private ViewHolder(Context context, int itemResourceId) {
sparseVies = new SparseArray<View>();
convertView = LayoutInflater.from(context).inflate(itemResourceId, null);
convertView.setTag(this);
}

private ViewHolder(Context context, int itemResourceId,ViewGroup viewGroup) {
sparseVies = new SparseArray<View>();
convertView = LayoutInflater.from(context).inflate(itemResourceId, viewGroup);
convertView.setTag(this);
}


public static ViewHolder get(Context context, View convertView, int itemResourceId) {
if (convertView == null) {
return new ViewHolder(context, itemResourceId);
}
return (ViewHolder) convertView.getTag();
}

public static ViewHolder get(Context context, View convertView, int itemResourceId,ViewGroup vierGroup) {
if (convertView == null) {
return new ViewHolder(context, itemResourceId,vierGroup);
}
return (ViewHolder) convertView.getTag();
}


public <T extends View> T getView(int viewId) {
View view = sparseVies.get(viewId);
if (view == null) {
view = convertView.findViewById(viewId);
sparseVies.put(viewId, view);
}
return (T) view;
}

public <T extends View> T findViewById(int viewId) {
return getView(viewId);
}

public View getConvertView() {
return convertView;
}

}


 

那么任何Adapter根本不用重新建立 Viewholder 使用办法:

public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder mViewHolder = ViewHolder.get(getActivity(), convertView, R.layout.lv_item_message_call);

//convertView = getLayoutInflater().inflate(R.layout.lv_item_message_call, null);
ImageView img_avatar = (ImageView) mViewHolder.findViewById(R.id.img_avatar);
ImageView img_merchant = (ImageView) mViewHolder.findViewById(R.id.img_merchant);
View ll_call = mViewHolder.findViewById(R.id.ll_call);
ImageView img_call_type = (ImageView) mViewHolder.findViewById(R.id.img_call_type);
TextView tv_count = (TextView) mViewHolder.findViewById(R.id.tv_count);
TextView tv_name = (TextView) mViewHolder.findViewById(R.id.tv_name);
TextView tv_time = (TextView) mViewHolder.findViewById(R.id.tv_time);
ll_call.setOnClickListener(this);
return mViewHolder.getConvertView();
}


注意点:这个时候连convertview是不是为空都根本不用判断:

直接初始化ViewHolder了。因为提取的ViewHolder已做单独判断。精简完成!over

任何新建的Adapter里完全不必要新建一个ViewHolder所有的Adapter都可以用此ViewHolder.

关于ViewHolder的终极优化

 

ps:如果感觉此篇文章对你有所帮助。请赞助本人一点闲余资金,买个棒棒糖吃。

 

 

 关于ViewHolder的终极优化