- 设计思路
listview需要设计不同的item类型的时,考虑到以后item类型的扩展,还有不同类型item的复用,使用工厂模式,抽象item公共实现接口实现。
优点:可扩展性强,代码复用度高,执行效率高,复用了convertView和ViewHolder 具体实现
1),大体的思路是:给listview设置适配器,自定义一个适配器,这个适配器要实现getViewTypeCount和getItemViewType方法(getViewTypeCount返回值的大小一定要比type数值大,不然报数组越界异常),重点在getView方法返回的每个item的view(convertView),这里就用到工厂模式。
2),写一个工厂类,里面有个SparseArray<>集合,存放item的convertView,保证复用。再写一个getCreatorByViewType方法,根据不同的type生产不同的item对象。
3),为了复用和代码简洁,将每个item抽象出来View createView(int position, Object
data,View convertView, ViewGroup parent),—–MyBaseViewHolder
createViewHolder(),—-void init(Activity ctx, int
layoutResId)这三个方法,然后写一个抽象类实现其中的init(将context和布局的id传递过来)和createView(实现复用和蹦出布局)方法。
4),每个item的类,要实现createViewHolder方法,还有自己的holder类实现公共接口
总体设计类图
activity里面进行所有数据的初始化,实例化adapter和factory类,将myDataManager,myFactory作为参数传递给adapter
private void initData() {
myDataManager = new MyDataManager();
myDataManager.initData();
myFactory = new MyFactory();
myAdapter = new MyAdapter(this, myDataManager, myFactory);
listView.setAdapter(myAdapter);
}
适配器抽象出getview不同的操作,而这个viewholder类的复用封装给factory完成
public class MyAdapter extends BaseAdapter{
private Activity ctx;
private MyDataManager dataManager;
private MyFactory factory;
public MyAdapter(Activity ctx, MyDataManager dataManager, MyFactory factory) {
this.ctx=ctx;
this.dataManager=dataManager;
this.factory=factory;
}
@Override
public int getCount() {
return dataManager.dataList.size();
}
@Override
public Object getItem(int position) {
return dataManager.dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/* (non-Javadoc)
* @see android.widget.BaseAdapter#getViewTypeCount()
* 返回总共type的总数
*/
@Override
public int getViewTypeCount() {
return MyEntities.VIEWTYPE_ALL;
}
/* (non-Javadoc)
* @see android.widget.BaseAdapter#getItemViewType(int)
* 返回每个item的type
*/
@Override
public int getItemViewType(int position) {
return dataManager.viewTypeAllList.get(position);
}
/* (non-Javadoc)
* @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
* 返回每一个item的对象
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return factory.getCreatorByViewType(ctx, dataManager.viewTypeAllList.get(position), dataManager)
.createView(position, dataManager.dataList.get(position), convertView, parent);
}
}
factory类完成每个item的复用,采用SparseArray集合存储,根据datamanager不同的item类型的数据分配对应的item对象
private SparseArray<IMyCrator> mCreators = new SparseArray<IMyCrator>();
public IMyCrator getCreatorByViewType(Activity ctx, int viewType, MyDataManager dataManager) {
IMyCrator creator = mCreators.get(viewType);
if (creator != null) {
return creator;
}
switch (viewType) {
case MyEntities.VIEW_CRATPR1:
creator = new Crator1(ctx, dataManager);
break;
case MyEntities.VIEW_CRATOR2:
creator = new Crator2(ctx, dataManager);
break;
case MyEntities.VIEW_CRATOR3:
creator = new Crator3(ctx, dataManager);
break;
}
mCreators.put(viewType, creator);
return creator;
}
而最终实现不同的item的布局,就要用不同的Crator对象,为了以后item类型的扩展,给这个item抽象出不同的接口,和抽象类,子类只需要实现在getview里面不同的inflate布局和在布局上填充的内容的操作。具体的实现下载源码(付最后)
@Override
public MyBaseViewHolder createViewHolder() {
return new Holder1();
}
class Holder1 extends MyBaseViewHolder{
private TextView name;
private TextView type;
/* (non-Javadoc)
* @see com.song.testfactoryproductitem.MyBaseViewHolder#findViews(android.view.View)
*
*/
@Override
public void findViews(View convertView) {
name = (TextView) convertView.findViewById(R.id.name);
type = (TextView) convertView.findViewById(R.id.type);
}
/* (non-Javadoc)
* @see com.song.testfactoryproductitem.MyBaseViewHolder#setData(java.lang.Object, android.view.View, int)
* 给holder设置数据
*/
@Override
public void setData(Object data, View convertView, int position) {
if (!(data instanceof Entry2)) {
return;
}
Entry2 e=(Entry2)data;
name.setText(e.getName());
type.setText(e.getType());
}
}
//AbsMyCrator类实现
private Activity ctx;
private int layoutResId;
/* (non-Javadoc)
* @see com.song.testfactoryproductitem.IMyCrator#createView(int, java.lang.Object, android.view.View, android.view.ViewGroup)
* 初始化每个item的convertView
*/
@Override
public View createView(int position, Object data, View convertView, ViewGroup parent) {
MyBaseViewHolder holder = null;
if (convertView == null) {
holder = createViewHolder();
convertView = LayoutInflater.from(ctx).inflate(layoutResId, parent, false);
holder.findViews(convertView);
convertView.setTag(holder);
} else {
holder = (MyBaseViewHolder) convertView.getTag();
}
holder.setData(data, convertView, position);
convertView.setId(position);
return convertView;
}
@Override
public void init(Activity ctx, int layoutResId) {
this.ctx=ctx;
this.layoutResId=layoutResId;
}
有什么不清晰的欢迎留言
付源码http://download.youkuaiyun.com/detail/xiangxi101/9341641
/**
* --------------
* 欢迎转载 | 转载请注明
* --------------
* 如果对你有帮助,请点击|顶|
* --------------
* 请保持谦逊 | 你会走的更远
* --------------
* @author css
* @github https://github.com/songsongbrother
* @blog http://blog.youkuaiyun.com/xiangxi101
*/