ListView,GridView万能适配器 - 下
(不相同行布局)
博主做了好多项目,没有一个项目敢说用不到ListView(下拉刷新ListView也算) ListView是安卓初级到安卓中级的纽带,学好ListView控件是很有必要。
注:刚接触不同item(行布局)的可参考:
http://blog.csdn.net/gjy_it/article/details/52014075
请参考上一张相同行布局的万能适配器:(上一章,不同行布局的万能适配器的地址:点击跳转)
(在这里,我就不进行DEMO演示,兴趣的要自己去动手实践)
在上一篇也提到了listview的重要性,在开发过程中非常的需要这个控件,了解之后也可以继承此控件做更多自己想要的控件。RecycleView 是最近很热门的一个控件,很多人都说它代替了ListView,GridView 增加了许多动画,性能也更好了。 这个是确实的,但是并不是多有的都需要RecycleView, 有时候ListView,GridView 在某些场景下也许会比RecycleView 来的好,这个就是要具体情况具体分析,不能一味得去追求,吊死在一棵树上。虽然我也在用RecycleView,但是我更爱ListView.
同时,在上篇提到了ListView 、什么叫万能适配器,如何使用,为什么要用万能适配器。(当然这个不必须的,但是我觉得很有必要,这知识我相对来说的), 以及提到了相同行布局的万能适配器的用法。
在上一章节提到的相同行布局的基础上,做这个不同行布局的万能适配器就轻松得多, 因为在不同行布局中,只需要在抽象适配器中实现即可,并不用在ViewHolder中做文章,ViewHolder只是管理控件而已 这样理解吧。
先看下结构 目录:
这里不演示Demo 但是会介绍每个方法的作用,需要的可自行实践。
CommonAdapter4GrideView 为相同行布局的抽象类适配器
CommonAdapter 为不同行布局的抽象类适配器
老样子看下源码:
package com.gjy.superadapter;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public abstract class CommonAdapter<T> extends BaseAdapter {
protected LayoutInflater mInflater;
protected Context context;
protected List<T> mDatas;
protected final int mLayoutId;
protected List<Integer> mLayouts;
public CommonAdapter(Context context,List<T> mdaList,int mLayoutId) {
this.context=context;
this.mDatas=mdaList;
this.mInflater = LayoutInflater.from(context);
this.mLayoutId=mLayoutId;
}
public CommonAdapter(Context context,List<T> mdaList,List<Integer> mLayoutIds)
{
this.context=context;
this.mDatas=mdaList;
this.mInflater = LayoutInflater.from(context);
this.mLayouts=mLayoutIds;
mLayoutId=0;
}
/**
* 获取类型
* */
@Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
int type = getType(position,mDatas.get(position));
return type;
}
/**
* 获取类型总数
* */
@Override
public int getViewTypeCount() {
int typeCount = getTypeCount();
return typeCount;
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public T getItem(int position) {
// TODO Auto-generated method stub
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
//更改传进去的布局即可
final ViewHolder viewHolder=getViewHolder(position, convertView, parent,type);
//抽象一个方法出去 方便进行实现 控件的数据绑定
convert(viewHolder,type,position);
return viewHolder.getConvertview();
}
/**
* 对控件进行操作
* */
public abstract void convert(ViewHolder helper,int type,int position);
/**
* 获取行布局的类型
* */
public abstract int getType(int position,T item);
/**
* 获取行布局的类型数量
* */
public abstract int getTypeCount();
private ViewHolder getViewHolder(int position,View converView,ViewGroup parent,int type)
{
return ViewHolder.get(context, converView, parent, mLayouts.get(type), position);
}
}
1.看下类的构造函数:
public CommonAdapter(Context context,List<T> mdaList,List<Integer> mLayoutIds)
{
this.context=context;
this.mDatas=mdaList;
this.mInflater = LayoutInflater.from(context);
this.mLayouts=mLayoutIds;
mLayoutId=0;
}
看这个构造函数即可。首先和相同行布局的很像, 不同的是:List<Integer> mLayoutIds
这个为布局的id, 在不同行布局中,每个item都对应着一个xml , 那么需只要传入XML 转为View的集 合, 抽象类会自行管理行布局。
(注意:View 要随着 种类的type 依次存入集合,也就是说第一种的行布局类型就对应这mLayoutIds 这个 集合里面的第1个View)
/**
* 对控件进行操作
* */
public abstract void convert(ViewHolder helper,int type,int position);
/**
* 获取行布局的类型
* */
public abstract int getType(int position,T item);
/**
* 获取行布局的类型数量
* */
public abstract int getTypeCount();
private ViewHolder getViewHolder(int position,View converView,ViewGroup parent,int type)
{
return ViewHolder.get(context, converView, parent, mLayouts.get(type), position);
}
1.public abstract void convert(ViewHolder helper,int type,int position);
这个抽象方法跟相同行布局的很相像。但是多了一个,int type类型的。这个类型就是传入出去 让外面实 现抽象的方法能根据这个类型做一些相对应的逻辑操作。其余部分与相同行布局的一样。
2.getViewHolder 这个方法也一样 传入想对应的布局绑定ViewHolder。这个也与相同行布局的用法一 样。
3. public abstract int getType(int position,T item);
那个gettype 方法在此抽象类中被public int getItemViewType(int position) 这个方法体中所调用,
在做复杂的数据情况下,可能会根据自定义的 判断方式来确定是哪种type。
4.至于public abstract int getTypeCount(); 在上面源码中提到在public int getViewTypeCount()中调 用,但是也没有必要,因为种类的类型都已经被List<Integer> mLayoutIds 的Size 所确定,所以没有 必要在抽象方法出去,这个是多此一举,当然系版本已经改过来了,而且增添优化了许多功能。
*(重点) :
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
//更改传进去的布局即可
final ViewHolder viewHolder=getViewHolder(position, convertView, parent,type);
//抽象一个方法出去 方便进行实现 控件的数据绑定
convert(viewHolder,type,position);
return viewHolder.getConvertview();
}
这个的调用的顺序要仔细琢磨。获取类型->获取ViewHolder->最后进行实现。
最后看下用法:
demo地址: