ViewHolder baseadatper封装的万能适配器

再次声明:参考了鸿翔在慕课中的视频,这是视频地址,有兴趣的去看看http://www.imooc.com/learn/372


说一下我的理解:经过这种封装后的适配器,有非常高的复用性,会在开发中节省大量的时间和代码量;另外,最让我值得学习的是,这种封装的思想,在代码中如果一段代码,有重复利用的地方,则应该进行封装。还有就是,越来越感觉到设计模式的重要性。。。。


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



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值