通用型的listview/gridview适配器adapter

往往在项目中我会回遇到很多不同样式布局的listview/gridview的item布局或不同的实体类ban。假如我们有10个不同的实体类,10个不同的item布局,那我们是不是要去写10个adapter适配器,这样显然是重复的做了很多无用功。其实我们可以把其中公共的部分提出来。在activity中只需要传一个bean,布局文件和上下文即可。那么实现代码看下面:


package com.example.commonadaptertest.utils;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import java.util.List;

/**
 * 
 * 通用的ListView的BaseAdapter,所有的ListView的自定义adapter都可以继承这个类哦
 */
public abstract class ListViewAdapter<T> extends BaseAdapter {

    //为了让子类访问,于是将属性设置为protected
    protected Context mContext;
    protected List<T> mDatas;
    protected LayoutInflater mInflater;
    private int layoutId; //不同的ListView的item布局肯能不同,所以要把布局单独提取出来

    public ListViewAdapter(Context context, List<T> datas, int layoutId) {
        this.mContext = context;
        mInflater = LayoutInflater.from(context);
        this.mDatas = datas;
        this.layoutId = layoutId;
    }

    @Override
    public int getCount() {
        return mDatas.size();
    }

    @Override
    public T getItem(int position) {
        return mDatas.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //初始化ViewHolder,使用通用的ViewHolder,一样代码就搞定ViewHolder的初始化咯
        ViewHolder holder = ViewHolder.get(mContext, convertView, parent, layoutId, position);//layoutId就是单个item的布局
        convert(holder, getItem(position),position);
        return holder.getConvertView(); 
    }
    //将convert方法公布出去
    public abstract void convert(ViewHolder holder, T t,int position);

}
package com.example.commonadaptertest.utils;

import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class ViewHolder {

	private SparseArray<View> mViews;
	private int mPosition;
	private View mConvertView;

	public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
		this.mPosition = position;
		this.mViews = new SparseArray<View>();

		mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);

		mConvertView.setTag(this);

	}

	public static ViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int position) {
		if (convertView == null) {
			return new ViewHolder(context, parent, layoutId, position);
		} else {
			ViewHolder holder = (ViewHolder) convertView.getTag();
			holder.mPosition = position; //即时ViewHolder是复用的,但是position记得更新一下
			return holder;
		}
	}

	/*
    	通过viewId获取控件
	 */
	//使用的是泛型T,返回的是View的子类
	public <T extends View> T getView(int viewId) {
		View view = mViews.get(viewId);

		if (view == null) {
			view = mConvertView.findViewById(viewId);
			mViews.put(viewId, view);
		}

		return (T) view;
	}

	public View getConvertView() {
		return mConvertView;
	}

}

上面2个就是核心代码块。里面注释很清楚了。


package com.example.commonadaptertest;

import java.util.List;

import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

import com.example.commonadaptertest.entity.Bean;
import com.example.commonadaptertest.utils.ListViewAdapter;
import com.example.commonadaptertest.utils.ViewHolder;

public class ListViewAdapterWithViewHolder extends ListViewAdapter<Bean> {

    //MyAdapter需要一个Context,通过Context获得Layout.inflater,然后通过inflater加载item的布局
    public ListViewAdapterWithViewHolder(Context context, List<Bean> datas,int layoutId) {
        super(context, datas, layoutId);
    }

    @Override
    public void convert(ViewHolder holder, final Bean bean,final int position) {

        ((TextView) holder.getView(R.id.titleTv)).setText(bean.getTitle());
        ((TextView) holder.getView(R.id.descTv)).setText(bean.getDesc());
        ((TextView) holder.getView(R.id.timeTv)).setText(bean.getTime());
        ((TextView) holder.getView(R.id.phoneTv)).setText(bean.getPhone());
        
        ((TextView) holder.getView(R.id.phoneTv)).setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Toast.makeText(mContext, "position:"+position+"内容:"+bean.getPhone(), Toast.LENGTH_SHORT).show();
			}
		});

    }
}

上面代码块就是设值写逻辑的地方,当然里面的点击事件也可以进一步优化。这个就你们自己去提取吧,这里不多说了。然后就是在activity中的调用,如下:

  listViewAdapterWithViewHolder = new ListViewAdapterWithViewHolder(this, mDatas,R.layout.item_listview);

        listView.setAdapter(listViewAdapterWithViewHolder);

大功告成了!!!

源码点击这里




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值