这篇文章主要介绍了Android数据适配器ViewHolder怎么用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android数据适配器ViewHolder怎么用文章都会有所收获,下面我们一起来看看吧。
在使用Listview或GridView的时候,往往需要自定义数据适配器,一般都要覆写getView(),在该方法中有一个convertView参数,该参数就是用来加载数据时的View。
初学者简单但低效的方式
public View getView(int position, View convertView, ViewGroup parent) { View item= inflater.inflate(R.layout.good_list_item, null, false); ImageView img = (ImageView) item.findViewById(R.id.img); TextView price = (TextView) item.findViewById(R.id.price); img.setImageResource(R.drawable.ic_launcher); price.setText("$"+list.get(position).price); return item; }
每次加载view,都要重新建立很多view对象,如果某条listview中有一万条数据,这种加载方式就歇菜了。
利用convertView
利用Android的Recycler机制,利用convertView来重新回收View,效率有了本质提高。View的每次创建是比较耗时的,因此对于getview方法传入的convertView应充分利用 != null的判断 。
public View getView(int position, View convertView, ViewGroup parent) { if(convertView==null){ convertView = inflater.inflate(R.layout.good_list_item, null, false); } TextView tv_price = (TextView)convertView.findViewById(R.id.price) ImageView iv = (ImageView)convertView.findViewByID(R.id.img); return convertView; }
使用ViewHolder
ViewHolder将需要缓存的view封装好,convertView的setTag才是将这些缓存起来供下次调用。 当你的listview里布局多样化的时候 viewholder的作用体现明显,效率再一次提高。 View的findViewById()方法也是比较耗时的,因此需要考虑只调用一次,之后就用View.getTag()方法来获得ViewHolder对象。
class ViewHolder{ ImageView img; TextView price; } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = new ViewHolder(); if(convertView==null){ convertView = inflater.inflate(R.layout.good_list_item, null, false); holder.img = (ImageView) convertView.findViewById(R.id.img); holder.price = (TextView) convertView.findViewById(R.id.price); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } //设置holder holder.img.setImageResource(R.drawable.ic_launcher); holder.price.setText("$"+list.get(position).price); return convertView; }
优雅的使用ViewHolder
使用ViewHolder时,每次一遍一遍的findViewById,一遍一遍在ViewHolder里面添加View的定义,view一多,是不是感觉烦爆了,base-adapter-helper这个类库似乎***的解决了这个问题。
其设计思想是使用 SparseArray来存储view的引用,代替了原本的ViewHolder,不用声明一大堆View,简洁明了。
我也自己动手写了一个简单版的ViewHolder。
public class ViewHolder{ private final SparseArray<View> views; private View convertView; private ViewHolder(View convertView){ this.views = new SparseArray<View>(); this.convertView = convertView; convertView.setTag(this); } public static ViewHolder get(View convertView){ if (convertView == null) { return new ViewHolder(convertView); } ViewHolder existedHolder = (ViewHolder) convertView.getTag(); return existedHolder; } public <T extends View> T getView(int viewId) { View view = views.get(viewId); if (view == null) { view = convertView.findViewById(viewId); views.put(viewId, view); } return (T) view; } }
使用的话就超级简单和简洁了:
public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(context) .inflate(R.layout.good_list_item, null, false); } ViewHolder mViewHolder = ViewHolder.get(convertView); TextView price = mViewHolder.getView(R.id.price); //...其他getView return convertView; }
关于“Android数据适配器ViewHolder怎么用”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Android数据适配器ViewHolder怎么用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。