传统的通过定义对象,运用面向对象的封装特性,实现视图的缓存,这里使用一种快速而便捷的缓存方式——SparseArray,此数据结构是通过Key和Value的index实现的,无论查询和插入效率,比HashMap高很多,缺点是key必须是int类型。
1.使用Sparse代理传统的ViewHolder的实现方法
/**
* 构建ViewHolder,并且返回所需要查找的View,需要的便会加载,不需要的不加载,效率更高
* @param layoutView 主布局
* @param childId 子View
* @return
*/
@SuppressWarnings("unchecked")
public static <T extends View> T injectViewHolder(View layoutView,int childId){
SparseArray<T> sparseArray = (SparseArray<T>) layoutView.getTag();
if(sparseArray==null)
{
sparseArray = new SparseArray<T>();
layoutView.setTag(sparseArray);
}
T t = sparseArray.get(childId);
if(t!=null)
{
return t;
}
t = (T) layoutView.findViewById(childId);
if(t!=null)
{
sparseArray.put(childId, t);
}
return t;
}
2.SparseArray存储和查找View的方法
View convertView = LayoutInflater.from(context).inflate(R.layout.list_card_item,null);
TextView flightDateTv = injectViewHolder(convertView, R.id.card_item_flightdate_tv);
TextView routeTv = injectViewHolder(convertView, R.id.card_item_route_tv);
这种同样可以实现ViewHolder而且SparseArray是个高速读取的数组,效率比Map好多了。
3.SparseArray的重要API
//根据Key值获取value
public E get(int key);
//根据Key值获取value,valueIfKeyNotFound表示value未找到或者key未映射时座位替代的value
public E get(int key, E valueIfKeyNotFound);
//删除
delete(int key);
//,底层调用了delete(int key)
remove(int key);
//按照索引删除
public void removeAt(int index);
//插入key=>value
public void put(int key, E value);
//数组大小
public int size();
//key所在的索引
public int indexOfValue(E value);
//索引对应的key
public int keyAt(int index);
//value所在的索引
public int indexOfValue(E value);
//索引对应的key
public E valueAt(int index);
在SparseArray中,分别利用来做键值映射,这点比使用数组和链表的HashMap效率高很多。
private int[] mKeys;
private Object[] mValues;
private int mSize;
在这里可知: key=>value所构成的映射中,他们的索index是完全相同的,即知道value,可通过indexOfValue->keyAt得到key值,也可以通过索引得到 key和value
SparseArray因此具有LinkedList的特性,无序性,也具有Map的特性,键值映射
Try doing it!