本文素材来自于http://www.jianshu.com/p/d6a76fd3ea5b
本文作者只是对于该作者的所写代码进行分析,详情源码请点击上面链接
万能适配器
--- 适配 listview Gridview RecyclerView##
首先所有的adapter 继承于BaseSuperAdapter这个类
public abstract class BaseSuperAdapter<T> extends RecyclerView.Adapter<SuperViewHolder>implements ListAdapter, SpinnerAdapter, IViewBindData<T, SuperViewHolder>,
ILayoutManager, IHeaderFooter
而这个父类继承了RecyclerView.Aapter
实现了上面的几个接口,使之可以兼容使用于listview ,RecyclerView等。
ILayoutManager 接口有以下两个方法
boolean hasLayoutManager();
RecyclerView.LayoutManager getLayoutManager();
分别是判断是否 LayoutManager 是否存在用于RecyclerView的适配
ListAdapter 的间接子类BaseAdapter是非常有名的。可以说ListAdapter 是很多listview适配器的父类,中间有两个方法
areAllItemsEnabledisEnabled
isEnabled
第一个方法表示是否在ListAdapter中的所有项都enabled,即是否所有项都selectable和clickable ,是boolean类型的
isEnabled 方法是用声明指定位置的项是否是enabled的
SpinnerAdapter这个接口是用于适配Spinner的
public View getDropDownView(int position, View convertView, ViewGroup parent);
而在这个代码中调用了一个getView 函数
public View getView(int position, View convertView, ViewGroup parent) {
SuperViewHolder holder = onCreate(convertView, parent, getItemViewType(position));
T item = getItem(position);
onBind(holder, getItemViewType(position), position, item);
return holder.itemView;
}
SuperViewHolder 类中写了各种ui 的绑定事件
setText(),setTextColor();等函数一个例子
@Override
public SuperViewHolder setTextColor(int viewId, ColorStateList colorStateList) {
TextView view = getView(viewId);
view.setTextColor(colorStateList);
return this;
}
这个类中还有个get方法
public static SuperViewHolder get(View convertView, View itemView) {
SuperViewHolder holder;
if (convertView == null) {
holder = new SuperViewHolder(itemView);
convertView = itemView;
convertView.setTag(holder);
} else {
holder = (SuperViewHolder) convertView.getTag();
}
return holder;
}
写过BaseAdapter应该对着这段代码很熟悉,如果不知请先从BaseAdapter学起。
public <T extends View> T getView(int id) {
View childView = childViews.get(id);
if (childView == null) {
childView = itemView.findViewById(id);
if (childView != null)
childViews.put(id, childView);
}
return (T) childView;
}
getView() 是根据id 获得这个ui控件,这个方法在之前的setText等方法中调用以获取该事件发生的ui空件。
在这里我想强调一点的所有的图片获取是用android 本身的像setImageUri等实现的,当图片过多时也许会出现oom问题,最好是改用其他第三方库或者是自己写的,在这里我就不写这些了。
IViewBindData<T, VH>
VH onCreate(View convertView, ViewGroup parent, int viewType);
void onBind(VH holder, int viewType, int layoutPosition, T item);
这个接口有onCreate和onBind 两个方法 这个在下面会提到
addHeaderView
addFooterView
removeHeaderView
removeFooterView
这三个函数主要靠notifyItemRemoved notifyItemInserted 两个函数
例子:notifyItemRemoved(0)移除第一个item
但是这有一个不同就是RecyclerView有Girdview所以有一个方法
private void ifGridLayoutManager() {
final RecyclerView.LayoutManager layoutManager = getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
final GridLayoutManager.SpanSizeLookup originalSpanSizeLookup =
((GridLayoutManager) layoutManager).getSpanSizeLookup();
((GridLayoutManager) layoutManager).setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return (isHeaderView(position) || isFooterView(position)) ?
((GridLayoutManager) layoutManager).getSpanCount() :
originalSpanSizeLookup.getSpanSize(position);
}
});
}
}
这个方法是使header和footerfooter这两布局和宽度与屏幕相同
@Override
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable = new DataSetObservable();
mDataSetObservable.registerObserver(observer);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
mDataSetObservable = null;
}
这两个方法是用于更新所用,如果不知DataSetObserver ,可以去google 一下 不过看到这个我就想去了Rxjava
那么这个父类就到这里
这个包中还有一个SuperAdapter类继承于BaseSuperAdapter
@Override
public SuperViewHolder onCreate(View convertView, ViewGroup parent, int viewType) {
final SuperViewHolder holder;
if (mMulItemViewType != null) {
holder = SuperViewHolder.get(convertView, convertView == null ?
mLayoutInflater.inflate(mMulItemViewType.getLayoutId(viewType), parent, false) : null);
} else {
holder = SuperViewHolder.get(convertView, convertView == null ?
mLayoutInflater.inflate(mLayoutResId, parent, false) : null);
}
return holder;
}
在这里用了一个方法onCreate 这个就是上面我没写完的两个方法之一
获得holder是这个方法存在的目的
onBind 这个方法是为布局中的ui控件写下事件。这两个具体方法用法你们可以下载源码看
SimpleMulItemViewType
int getViewTypeCount();
int getItemViewType(int position, T t);
int getLayoutId(int viewType);
三个方法是第一个是得到listview 的item的类型 第二个是返回一个int类型去给getLayoutId 用来调用不同的布局文件
也就是这个是实现不同布局的listview等 例如对话
其实这个适配器还有很多小功能,甚至自己可以加很多小功能,比如在Gridview 最后一个item加一个特别的item 这就自己琢磨了。
我也只介绍到这里了,最好是自己去看琢磨,对于菜鸟还是非常有帮助的。在此也感谢一下那位作者。