ViewHolder baseadatper封装的万能适配器
2016-03-08 12:31
686 查看
再次声明:参考了鸿翔在慕课中的视频,这是视频地址,有兴趣的去看看http://www.imooc.com/learn/372
说一下我的理解:经过这种封装后的适配器,有非常高的复用性,会在开发中节省大量的时间和代码量;另外,最让我值得学习的是,这种封装的思想,在代码中如果一段代码,有重复利用的地方,则应该进行封装。还有就是,越来越感觉到设计模式的重要性。。。。
1:写一个独立的ViewHolder类,和传统的ViewHolder内部类一样,防止控件的反复加载
2:这个类中的核心方法就是一个构造函数和一个对外公布方法
注:外部调用getinstance方法,如果contentview为null,怎就会走到构造函数中,构造函数中写了初始化的数据,如果不是null,则从tag中获取,这里的position要赋值一下,防止position重用,造成界面混乱。
3:封装自己的baseadapter
注:这里是泛型E,一定是泛型,因为每一个listview或者gridview,都有自己的bean(实体类),不能写死
4:这个类中的和新方法是:
注:写一个抽象方法,子类必须去实现,同时把viewholder类,和泛型的实体类对象传递出去
5:子类继承自己的父类适配器
注:就只有上边一个方法和一个构造函数,这个构造函数一定要有。这样的话,完全可以写成内部类,不过Dome毕竟没有这个复杂的控件和逻辑,所以在实际开发中,还要根据具体情况分析;
另外,对于checkbox混乱问题,上边的代码就是,一定要在bean实体类中,写一个boolean来记录选中状态。
下面是viewholder类中的完整代码:
自己的baseadapter中的完整代码:
注:里边有一些更新数据的方法,因为不同的项目,有不同的需求,不一定要在构造函数中传递数据。总之这里还有诸多没有加入的方法,因为当用的地方不一样,就会逐步的去完善。。。。
下面是Dome下载的地址:
http://download.csdn.net/detail/jiajia1112223/9455334
说一下我的理解:经过这种封装后的适配器,有非常高的复用性,会在开发中节省大量的时间和代码量;另外,最让我值得学习的是,这种封装的思想,在代码中如果一段代码,有重复利用的地方,则应该进行封装。还有就是,越来越感觉到设计模式的重要性。。。。
1:写一个独立的ViewHolder类,和传统的ViewHolder内部类一样,防止控件的反复加载
/** * 封装的ViewHolder类 * @author Administrator * */ public class listview_ViewHolder {
2:这个类中的核心方法就是一个构造函数和一个对外公布方法
public class listview_ViewHolder { private LayoutInflater inflater; private int position; //integer类型的key,运行速度比较快 private SparseArray<View> lists; private listview_ViewHolder holder; private View contenView; private listview_ViewHolder(Context context ,ViewGroup parent ,int layoutId,int position) { lists=new SparseArray<View>(); contenView=LayoutInflater.from(context).inflate(layoutId, parent,false); contenView.setTag(this); } /** * 对外公布的方法,相当于传统Getview()方法中,viewholder和contentview设置tag * @param context * @param position * @param contentView * @param parent * @param layoutID * @return */ public static listview_ViewHolder getInstance(Context context,int position,View contentView,ViewGroup parent,int layoutID) { if(contentView==null) { return new listview_ViewHolder(context, parent, layoutID, position); }else{ listview_ViewHolder tag = (listview_ViewHolder) contentView.getTag(); //position不能重复使用 tag.position=position; return tag; } }
注:外部调用getinstance方法,如果contentview为null,怎就会走到构造函数中,构造函数中写了初始化的数据,如果不是null,则从tag中获取,这里的position要赋值一下,防止position重用,造成界面混乱。
3:封装自己的baseadapter
/** * 封装好的父类适配器, * 跟封装好viewholder结合使用 * @author Administrator * * @param <E> */ public abstract class myBaseAdatper<E> extends BaseAdapter {
注:这里是泛型E,一定是泛型,因为每一个listview或者gridview,都有自己的bean(实体类),不能写死
4:这个类中的和新方法是:
@Override public View getView(int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub listview_ViewHolder viewHolder=listview_ViewHolder.getInstance(context, arg0, arg1, arg2, layoutId); //调用一下方法,吧参数传出去 myGetView(viewHolder, getItem(arg0)); return viewHolder.getContenView(); } public abstract void myGetView(listview_ViewHolder viewHolder,E e);
注:写一个抽象方法,子类必须去实现,同时把viewholder类,和泛型的实体类对象传递出去
5:子类继承自己的父类适配器
public class holderAdatper extends myBaseAdatper<mainlist_mode>{ /** * 这个构造函数必须要有,因为继承父类的构造函数,其中的初始化参数要拿到这个子类中, * 不然就会包错误 * * * 当调用适配器的时候,就会把参数传到父类适配器中,然后就可以给到viewHolder中 * @param lists * @param context * @param layoutId */ public holderAdatper(List<mainlist_mode> lists, Context context, int layoutId) { super(lists, context, layoutId); // TODO Auto-generated constructor stub } @Override public void myGetView(listview_ViewHolder viewHolder, final mainlist_mode e) { viewHolder.SetTextView(R.id.id_item_aire, e.getAire()); viewHolder.SetTextView(R.id.id_item_diqu, e.getDiqu()); viewHolder.SetTextView(R.id.id_item_name, e.getName()); viewHolder.SetTextView(R.id.id_item_number, e.getNumber()); final CheckBox cb=viewHolder.mFindViewById(R.id.id_item_ck); //checkbox,设置是否选中,设置的事实体类中的值,而不是点击之后的值 cb.setChecked(e.isChecked()); //checkbox的点击事件中,吧点击的值给实体类 cb.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub e.setChecked(cb.isChecked()); } }); } }
注:就只有上边一个方法和一个构造函数,这个构造函数一定要有。这样的话,完全可以写成内部类,不过Dome毕竟没有这个复杂的控件和逻辑,所以在实际开发中,还要根据具体情况分析;
另外,对于checkbox混乱问题,上边的代码就是,一定要在bean实体类中,写一个boolean来记录选中状态。
下面是viewholder类中的完整代码:
package com.ljg.cewanneng.app.ViewHolder;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
/** * 封装的ViewHolder类 * @author Administrator * */ public class listview_ViewHolder {
private LayoutInflater inflater;
private int position;
//integer类型的key,运行速度比较快
private SparseArray<View> lists;
private listview_ViewHolder holder;
private View contenView;
private listview_ViewHolder(Context context ,ViewGroup parent ,int layoutId,int position)
{
lists=new SparseArray<View>();
contenView=LayoutInflater.from(context).inflate(layoutId, parent,false);
contenView.setTag(this);
}
/**
* 对外公布的方法,相当于传统Getview()方法中,viewholder和contentview设置tag
* @param context
* @param position
* @param contentView
* @param parent
* @param layoutID
* @return
*/
public static listview_ViewHolder getInstance(Context context,int position,View contentView,ViewGroup parent,int layoutID)
{
if(contentView==null)
{
return new listview_ViewHolder(context, parent, layoutID, position);
}else{
listview_ViewHolder tag = (listview_ViewHolder) contentView.getTag();
//position不能重复使用
tag.position=position;
return tag;
}
}
/**
* 在这个viewholder中对contenview进行layoutinflater进行绑定的
* 所以baseAdatper的getview()方法中的返回值用这里的contentview;
* @return
*/
public View getContenView() {
return contenView;
}
/**
* 所有空间的绑定Id的方法,用SparseArray对绑定过的View进行保存
* @param ViewId
* @return
*/
public <T extends View> T mFindViewById(int ViewId)
{
View v=lists.get(ViewId);
if(v==null)
{
v=contenView.findViewById(ViewId);
lists.put(ViewId, v);
}
return (T) v;
}
/**
* 给TextView类型的的控件赋值
* @param ViewId
* @param str
*/
public listview_ViewHolder SetTextView(int ViewId,String str){
//调用getview方法,绑定了所有控件的ID
TextView tv=mFindViewById(ViewId);
tv.setText(str);
return this;
}
/**
* 还可以写设置imageview的方法
*/
public void setImageView(int ViewId,Bitmap bitmap)
{
ImageView im=mFindViewById(ViewId);
im.setImageBitmap(bitmap);
}
}
自己的baseadapter中的完整代码:
package com.ljg.cewanneng.app.ViewHolder;
import java.util.ArrayList;
import java.util.List;
import com.ljg.cewanneng.app.ViewHolder.listview_ViewHolder;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
/** * 封装好的父类适配器, * 跟封装好viewholder结合使用 * @author Administrator * * @param <E> */ public abstract class myBaseAdatper<E> extends BaseAdapter {
protected LayoutInflater inflater;
protected List<E> lists=new ArrayList<E>();
protected Context context;
private int layoutId;
public myBaseAdatper( List<E> lists,
Context context, int layoutId) {
super();
this.lists = lists;
this.context = context;
this.layoutId = layoutId;
inflater=LayoutInflater.from(context);
}
/**
* 不传递集合数据的构造函数
* @param context
* @param layoutId
*/
public myBaseAdatper(Context context, int layoutId) {
super();
this.context = context;
this.layoutId = layoutId;
inflater=LayoutInflater.from(context);
}
/**
* 删除所有数据方法
* @param list
*/
public void RemoveAllLists(List<E> list){
lists.removeAll(list);
notifyDataSetChanged();
}
/**
* 删除数据的方法
* @param e
*/
public void removeList(E e)
{
lists.remove(e);
notifyDataSetChanged();
}
/**
* 更新数据到头不的方法
* @param e
*/
public void AddTopList(E e)
{
lists.add(0, e);
notifyDataSetChanged();
}
/**
* 刷新适配器的方法
*/
public void NotifyDataSetChanged()
{
this.NotifyDataSetChanged();
}
/**
* 一次添加多条数据
* @param list
*/
public void Addlists(List<E> list)
{
lists.addAll(list);
notifyDataSetChanged();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return lists.size();
}
@Override
public E getItem(int arg0) {
// TODO Auto-generated method stub
return lists.get(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
// TODO Auto-generated method stub
listview_ViewHolder viewHolder=listview_ViewHolder.getInstance(context, arg0, arg1, arg2, layoutId);
//调用一下方法,吧参数传出去
myGetView(viewHolder, getItem(arg0));
return viewHolder.getContenView();
}
public abstract void myGetView(listview_ViewHolder viewHolder,E e);
}
注:里边有一些更新数据的方法,因为不同的项目,有不同的需求,不一定要在构造函数中传递数据。总之这里还有诸多没有加入的方法,因为当用的地方不一样,就会逐步的去完善。。。。
下面是Dome下载的地址:
http://download.csdn.net/detail/jiajia1112223/9455334
相关文章推荐
- PHP无限分类原理和几种实现方法
- ThinkPHP分页及保持分页参数
- Zend Framework教程之Autoloading用法详解
- php内存处理须知【转】
- php设计模式 DAO(数据访问对象模式)
- Zend Framework教程之Resource Autoloading用法实例
- php修改系统默认时间
- php递归函数的理解
- PHP中怎样创建一个空对象?
- Hbase使用MultiTableOutputFormat实现多表输出MapReduce job
- 上传图片代码(chuantouxiang.php+touxiangchuli.php)
- php学习笔记之:环境配置(一)
- PHP 面向对面规范 PSR-0 小谈
- php.ini开放禁掉的函数以及重启服务的方法
- 让PHP更快的提供文件下载
- graph shortestpaths和pregel、mapReduceTriplets等中发送消息方向问题
- PHP数据加密技术之一---URL编码加密技术
- 正则表达式之PHP篇split 与 php函数explode
- 正则表达式之PHP篇replace,filter,grep
- zend studio输出中文乱码的问题