android 设计模式之Listview不同类型Item利用工厂模式的复用
来源:互联网 发布:网络神兽 编辑:程序博客网 时间:2024/06/05 00:35
- 设计思路
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.csdn.net/detail/xiangxi101/9341641
/**
* --------------
* 欢迎转载 | 转载请注明
* --------------
* 如果对你有帮助,请点击|顶|
* --------------
* 请保持谦逊 | 你会走的更远
* --------------
* @author css
* @github https://github.com/songsongbrother
* @blog http://blog.csdn.net/xiangxi101
*/
- android 设计模式之Listview不同类型Item利用工厂模式的复用
- Android 不同类型item的listview
- Android开发之ListView不同类型item的展示
- 缓存多种不同类型的数据(工厂设计模式)
- Android ListView实现不同类型的item
- Android设计模式之工厂设计模式
- android设计模式之简单工厂模式
- android设计模式之工厂方法模式
- android设计模式之抽象工厂模式
- Android 设计模式之工厂模式
- Android 设计模式学习之工厂模式
- Android设计模式之工厂模式 Factory
- Android设计模式之工厂模式
- Android设计模式之工厂模式 Factory
- Android设计模式之工厂模式 Factory
- android设计模式之工厂模式
- Android设计模式之工厂模式 Factory
- Android设计模式之 工厂方法模式
- hibernate cascade属性 all-delete-orphan
- Django 简介
- HDU 3976 (高斯消元 KCL方程)
- [bzoj3140][HNOI2013]消毒
- json详解
- android 设计模式之Listview不同类型Item利用工厂模式的复用
- mybatis一二级缓存
- CO-doc. number assignment not possible for bus.trans. COIN in CO area 1800 Message no. KC101
- App开发需要注意的8条
- C++中随机数的生成
- leetcode -- Sort List
- Linux下网络IP地址的转换函数
- 解决 android 高低版本 webView 里内容 自适应屏幕的终极方法
- leetcode Majority Element