老规矩先看效果:
咋一看和前几天写的那个用ListView嵌套GridView写的界面很像,但毕竟那个还是太Low了。http://blog.csdn.net/u012305710/article/details/50464982
Android已经推出了RecyclerView替换了ListView那实现起来肯定很简单了。
RecyclerView的Adapter中的
public BaseRecyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return getHolder(parent,viewType);
}
中的viewType就能对现在这个布局起到关键性的作用它能决定我们加载那种Holder。
但是获得这个viewType肯定是我们之前已经设置好了viewType,所以就需要重写Adapter中的:
@Override
public int getItemViewType(int position) {
if (mDatas.get(position).isHead()) {
return ITEM_TYPE.ITEM_TYPE_HEADER.ordinal();
} else {
return ITEM_TYPE.ITEM_TYPE_CONTENT.ordinal();
}
}
这样就能决定我们程序中显示两种布局了。
但是这样真的够了么?显然不行这样只会按照我们设置的GridLayoutManager按照统一的布局显示,不能像效果图一样标题栏能占满一行,这时候我们发现GridLayoutManager 提供了一个 setSpanSizeLookup() 的方法。可以让你传入一个继承自 GridLayoutManager.SpanSizeLookup 的类,在里面可以写每个position对应的item应跨越多少列。
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
boolean head = mDatas.get(position).isHead();
return head ? manager.getSpanCount() : 1;
}
});
这样就能大功告成了很简单。
在下面贴下代码对adapter进行了封装和对holder进行了封装:
这是基类的adaper:
public abstract class MyBaseRecyAdapter<T> extends RecyclerView.Adapter<BaseRecyHolder> {
private List<T> mDatas;
public MyBaseRecyAdapter(List<T> mDatas) {
this.mDatas = mDatas;
}
@Override
public BaseRecyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return getHolder(parent,viewType);
}
protected abstract BaseRecyHolder getHolder(ViewGroup parent, int viewType);
@Override
public void onBindViewHolder(BaseRecyHolder holder, int position) {
holder.setAllData(mDatas);
holder.setData(mDatas.get(position));
holder.setData(mDatas.get(position),mDatas.size(), position);
}
@Override
public int getItemCount() {
return mDatas.size();
}
}
下面是项目中的Adapter:
public class AllDeviceAdapter extends MyBaseRecyAdapter<AllDeviceResponse> {
private List<AllDeviceResponse> mDatas;
public enum ITEM_TYPE {
ITEM_TYPE_HEADER,
ITEM_TYPE_CONTENT,
}
public AllDeviceAdapter(List<AllDeviceResponse> mDatas) {
super(mDatas);
this.mDatas = mDatas;
}
@Override
protected BaseRecyHolder getHolder(ViewGroup parent, int viewType) {
LogUtil.e("getHolder viewtype" + viewType);
if (viewType == ITEM_TYPE.ITEM_TYPE_HEADER.ordinal()) {
View view = UIUtils.inflate(R.layout.view_heard);
return new AllDeviceHeaderHolder(view);
} else {
View view = UIUtils.inflate(R.layout.view_recylitem_all_device);
return new AllDeviceContentHolder(view);
}
}
@Override
public int getItemViewType(int position) {
if (mDatas.get(position).isHead()) {
return ITEM_TYPE.ITEM_TYPE_HEADER.ordinal();
} else {
return ITEM_TYPE.ITEM_TYPE_CONTENT.ordinal();
}
}
}
这样以后再写Adapter只要继承封装的Adapter实现其中的两个方法就可以了。
下面是对Holder的封装:
public abstract class BaseRecyHolder extends RecyclerView.ViewHolder {
private View view;
private T mDatas;
private int totalNumber,position;
private List allData;
public BaseRecyHolder(View itemView) {
super(itemView);
initView(itemView);
}
protected abstract View initView(View itemView);
public void setData(T mDatas) {
this.mDatas = mDatas;
refreshView();
}
public void setData(T mDatas,int totalNumber,int position) {
this.mDatas = mDatas;
this.totalNumber = totalNumber;
this.position = position;
}
public void setAllData(List<T> allData) {
this.allData = allData;
}
public T getData() {
return mDatas;
}
public List<T> getAllData() {
return allData;
}
protected abstract void refreshView();
}
这是项目中的Holder:
public class AllDeviceContentHolder extends BaseRecyHolder<AllDeviceResponse> {
@InjectView(R.id.img_icon)
ImageView imgIcon;
@InjectView(R.id.txt_name)
TextView txtName;
public AllDeviceContentHolder(View itemView) {
super(itemView);
}
@Override
protected View initView(View itemView) {
ButterKnife.inject(this, itemView);
return itemView;
}
@Override
protected void refreshView() {
AllDeviceResponse data = getData();
txtName.setText(data.getName());
}
}
这样就大功告成了。在这里还发现了个写的比较好的文章分享给大家:
http://xingrz.me/2014/2014-11-25/meizhi.html