ListView是非常常用android 控件,而对于ListView的优化,大家都想起了viewHolder模式了,很多人都写得滚瓜烂熟了。然而在Customizing Android ListView Rows by Subclassing中提到ViewHolder是一种愚昧的方式。
为什么?
以下是viewHolder模式的问题
-
Create a layout for your row view.
-
Create a “holder” class with fields to store child views of the row.
-
For each new inflated row, create a holder instance and assign its fields to the results of calling
findViewById(int)
for each child view. -
Set the instance of the holder as the top-level view’s tag with
setTag(Object).
-
Reuse (and cast) the holder object for reused row views.
那怎么办?
作者在文章中提出了新的思路,通过自定义的Layout来代替ViewHolder
关键代码:
自定义Layout:MyLayout
public class MyLayout extends RelativeLayout {
TextView tv_title; public MyLayout(Context context) { super(context); init(context); } private void init(Context context) { View view = LayoutInflater.from(context).inflate(R.layout.item_demo, this); tv_title = (TextView) view.findViewById(R.id.tv_title); } public void setData(String title) { tv_title.setText(title); } }
MyAdapter
public class MyAdapter extends BaseAdapter { private Context mContext; private List<String> mList; public MyAdapter(Context context, List<String> list) { mContext = context; mList = list; } @Override public int getCount() { return mList == null ? 0 : mList.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { MyLayout myLayout; if (convertView != null && convertView instanceof MyLayout) { myLayout = (MyLayout) convertView; } else { myLayout = new MyLayout(mContext); } myLayout.setData(mList.get(position)); return myLayout; } }
done