您的位置:首页 > 移动开发 > Android开发

android通用listview和gridview万能适配器实现的两种方式

2016-03-04 12:11 826 查看
      Listview和gridview是超级常用组件,于是乎,应该封装一下直接拿来用用而不是每次都写Adapter,这样多么的麻烦是不。虽然国内外大牛都有封装过,但是我总结了两个封装好的Adapter分享出来供使用。直接上代码和例子吧,就不啰嗦了。

第一种方式的CommonAdapter:

 

import java.util.List;

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

/**
* 万能适配器
*
* @author Mr.Himan
*
* @param <T>
*            数据源的数据类型
*/
public abstract class CommonAdapter<T> extends BaseAdapter {

/**
* 上下文
*/
protected Context mContext;
/**
* 数据源
*/
protected List<T> listDatas;
/**
* Item布局ID
*/
protected int layoutId;

public CommonAdapter(Context context, List<T> listDatas, int layoutId) {
this.mContext = context;
this.listDatas = listDatas;
this.layoutId = layoutId;
}

@Override
public int getCount() {
return listDatas == null ? 0 : listDatas.size();
}

@Override
/**
* 获取当前点击的Item的数据时用
* 在onItemClick中 parent.getAdapter().getItem(),获取当前点击的Item的数据
*/
public Object getItem(int position) {
return listDatas.get(position);
}

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

@Override
/**
* 只关心这一个方法
*/
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = ViewHolder.getViewHolder(mContext, convertView,
parent, layoutId);
fillData(holder, position);
return holder.getMConvertView();
}

/**
*
* 抽象方法,用于子类实现,填充数据
* @param holder
* @param position
*/
protected abstract void fillData(ViewHolder holder, int position);

}
    和原来的自定义Adapter很相似,最多就是使用了泛型,结合ViewHolder和抽象方法,请看下面ViewHolder的封装。

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

/**
*
* @author Mr.Himan Holer的通用化处理
*
*/
public class ViewHolder {

/**
* View容器,用于存放Holer中的View
* 照顾下小白 SparseArray 是Android推荐使用的一个优化容器,相当于一个Map<integer,View>
*/
private SparseArray<View> mViews;

/**
* Item布局View convertView
*/
private View mConvertView;

public ViewHolder(Context context, ViewGroup parent, int layoutId) {
mViews = new SparseArray<View>();
mConvertView = LayoutInflater.from(context).inflate(layoutId, null);
mConvertView.setTag(this);
}

/**
* 获取ViewHolder
*
* @param context
*            上下文
* @param convertView
* @param parent
* @param layoutId
*            布局layout Id
* @param position
* @return
*/
public static ViewHolder getViewHolder(Context context, View convertView,
ViewGroup parent, int layoutId) {

if (convertView == null)
return new ViewHolder(context, parent, layoutId);
return (ViewHolder) convertView.getTag();
}

/**
* 获取Holder中的ItemView
*
* @param viewId
* @return
*/
@SuppressWarnings("unchecked")
public <T extends View> T getView(int viewId) {

View item = mViews.get(viewId);
if (item == null) {
item = mConvertView.findViewById(viewId);
mViews.put(viewId, item);
}
return (T) item;
}

/**
* 获取convertView
*
* @return
*/
public View getMConvertView() {
return mConvertView;
}
}
其中还使用了优化容器SparseArray,这个容器是最近大牛们使用的非常火的容器,效率高出Map非常之多,而且最重要的是非常节约内存。

下面是使用例子:

import java.util.List;

import android.content.Context;
import android.widget.TextView;

import com.css.volunteer.bean.VolTeamItem;
import com.css.volunteer.bitmap.BitmapHelper;
import com.css.volunteer.manager.R;
import com.css.volunteer.view.CustomImageView;

public class VolTeamAdapter extends CommonAdapter<Bean> {

private List<Bean> item;    //JavaBean类自己写咯
public VolTeamAdapter(Context context, List<Bean> listDatas,
int layoutId) {
super(context, listDatas, layoutId);
this.item = listDatas;
}

@Override
protected void fillData(ViewHolder holder, int position) {
TextView actNum = holder.getView(R.id.team_item_active_num);
TextView time = holder.getView(R.id.team_item_time);
TextView title = holder.getView(R.id.team_item_title);
CustomImageView icon = holder.getView(R.id.team_item_icon);
Beanitem = listDatas.get(position);
actNum.setText(String.valueOf(item.getActiveSum()) + "个");
time.setText(String.valueOf(item.getTimeSum()) + "h");
title.setText(item.getName());
BitmapHelper.getInstance(context).display(icon, item.getPhoto());
}

}


各种使用例子都有,只要实现这个方法,就可以直接使用,gridview的使用方式一致,使用起来那叫一个方便。

第二种适配器的CommonAdapter:

package com.sgucai.convertnumber.adapter;

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

import com.sgucai.convertnumber.viewholder.ViewHolder;

import java.util.List;

/**
* Created by Administrator on 2015/11/4.
*/
public abstract class CommonAdapter<T> extends BaseAdapter {

protected List<T> mDatas;

protected LayoutInflater inflater;

protected Context mContext;

protected int layoutId;

public CommonAdapter(Context context ,List<T> mDatas,int layoutId){

inflater = LayoutInflater.from(context);

this.mContext = context;

this.mDatas = mDatas;

this.layoutId = layoutId;
}
@Override
public int getCount() {
int count = 0 ;
if(mDatas!=null){
count = mDatas.size();
}
return count;

}

@Override
public Object getItem(int position) {

return null;
}

@Override
public long getItemId(int position) {

return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder viewHolder = getViewHolder(position,convertView,parent);

convertView((int) getItemId(position),viewHolder, (T) getItem(position));

return viewHolder.getConverView();
}

public abstract void convertView(int position,ViewHolder viewHolder, T item);

public ViewHolder getViewHolder(int position, View convertView, ViewGroup parent){

return ViewHolder.getViewHolder(mContext,convertView,parent, layoutId,position);

}
}
这个适配器的Adapter的封装是不是和第一个有很多不同,但是核心部分封装几乎都是相似的。接下来看看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;

/**
* Created by Administrator on 2015/11/4.
*
* 必须保证view的Id不一样
*/

public class ViewHolder {

//用于存储view的集合
private SparseArray<View> mViews;

//填充布局的View
private View mConvertView;

private int position;

public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {

this.mViews = new SparseArray<View>();

this.position = position;

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

//设置tag
mConvertView.setTag(this);

}

/**
* 获取viewholder对象
*/
public static ViewHolder getViewHolder(Context context, View convertView, ViewGroup parent, int layoutID, int position) {

if(convertView == null){

return new ViewHolder(context,parent,layoutID,position);
}

return (ViewHolder) convertView.getTag();
}

/**
* 获取布局中的控件
*/

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 getConverView(){

return mConvertView;
}

/**
* text设置文本
*/
public ViewHolder setText(int textViewId, String text){

TextView tv = getView(textViewId);

tv.setText(text);

return this;
}

/**
* 为image设置本地drawable图片
*/
public ViewHolder setImageResourse(int imageViewId,int drawable){

ImageView imageView = getView(imageViewId);

imageView.setImageResource(drawable);

return this;
}

/**
* 为ImageView设置bitmap图片
*/
public ViewHolder setImageBitmap(int imageViewId, Bitmap bitmap){

ImageView imageView = getView(imageViewId);

imageView.setImageBitmap(bitmap);

return this;
}
<pre name="code" class="java">/**
* 设置Text ForegroundColorSpan的值
*
* @param viewId
* @param ForegroundColorSpan
*/
public ViewHolder setText(int viewId, SpannableStringBuilder span) {
TextView tv = getView(viewId);
tv.setText(span);
return this;
}

/**
* 设置文本颜色
*
* @param viewId
* @param color
* @return
*/
public ViewHolder setTextColor(int viewId, int color) {
TextView tv = getView(viewId);
tv.setTextColor(color);
return this;
}

/**
* 设置文本颜色,使用资源文件中的颜色
*
* @param viewId 指定控件的id
* @param resColorId 资源文件中color的id
* @return
*/
@SuppressWarnings("deprecation")
public ViewHolder setTextColorRes(int viewId, int resColorId) {
TextView tv = getView(viewId);
tv.setTextColor(mContext.getResources().getColor(resColorId));
return this;
}

/**
* 给对象设置Tag
*
* @param viewId
* @param key
* @param tag
* @return
*/
public ViewHolder setTag(int viewId, int key, Object tag) {
View view = getView(viewId);
view.setTag(key, tag);
return this;
}

/**
* 给View对象设置Tag
*
* @param viewId
* @param tag
* @return
*/
public ViewHolder setTag(int viewId, Object tag) {
View view = getView(viewId);
view.setTag(tag);
return this;
}

/**
* 给控件设置点击事件的监听器
*
* @return
*/
public ViewHolder setOnClickListener(int viewId, OnClickListener listener) {
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}

/**
* 设置TextView的Drawable
*
* @param viewId
* @param location
*            图片位置 left top right down
* @param ImageId
*/
@SuppressWarnings("deprecation")
public ViewHolder setTextDrawable(int viewId, String location, int ImageId) {
TextView tv = getView(viewId);
if (location != null && location.length() != 0) {
Drawable img = mContext.getResources().getDrawable(ImageId);
img.setBounds(0, 0, img.getMinimumWidth(), img.getMinimumHeight());
if ("left".equals(location)) {
tv.setCompoundDrawables(img, null, null, null);
} else if ("top".equals(location)) {
tv.setCompoundDrawables(null, img, null, null);
} else if ("right".equals(location)) {
tv.setCompoundDrawables(null, null, img, null);
} else if ("down".equals(location)) {
tv.setCompoundDrawables(null, null, null, img);
}
} else {
tv.setCompoundDrawables(null, null, null, null);
}
return this;
}
/**
* 设置ImageView本地图片
*
* @param viewId
* @param ImageId
*/
@SuppressWarnings("deprecation")
public ViewHolder setImageView(int viewId, int imageId) {
ImageView iv = getView(viewId);
iv.setImageDrawable(mContext.getResources().getDrawable(imageId));
return this;
}

/**
* 设置九宫格
*
* @param viewId
* @param baseAdapter
*/
public ViewHolder setGridViewAdapter(int viewId, BaseAdapter baseAdapter) {
GridView gv = getView(viewId);
gv.setAdapter(baseAdapter);
return this;
}

public ViewHolder updateGridViewLayoutParameters(int viewId, int colNum) {
DefineGridView dgv = getView(viewId);
GridViewUtil.updateGridViewLayoutParams(dgv, colNum);
return this;
}

/**
* 设置控件的Clickable
*
* @param viewId
* @param clickable
* @return
*/
public ViewHolder setClickable(int viewId, boolean clickable) {
View view = getView(viewId);
view.setClickable(clickable);
return this;
}

/**
* 设置控件的Enable
*
* @param viewId
* @param isEnable
* @return
*/
public ViewHolder setEnable(int viewId, boolean isEnable) {
View view = getView(viewId);
view.setEnabled(isEnable);
return this;
}

/**
* 设置控件的Pressed
*
* @param viewId
* @param pressed
* @return
*/
public ViewHolder setPressed(int viewId, boolean pressed) {
View view = getView(viewId);
view.setPressed(pressed);
return this;
}

/**
* 设置控件的Selected
* @param viewId
* @param selected
* @return
*/
public ViewHolder setSelected(int viewId, boolean selected) {
View view = getView(viewId);
view.setSelected(selected);
return this;
}

/**
* 设置布局背景
*
* @param viewId
* @param resid
*/
public ViewHolder setBackground(int viewId, int resid) {
View view = getView(viewId);
view.setBackgroundResource(resid);
return this;
}

/**
* 设置控件是否隐藏
*
*/
public ViewHolder setVisibility(int viewId, boolean visible) {
View view = getView(viewId);
if (visible) {
view.setVisibility(View.VISIBLE);
} else {
view.setVisibility(View.GONE);
}
return this;
}

/**
* 设置控件是否隐藏
*/
public ViewHolder setVisibility(int viewId, int visibility) {
View view = getView(viewId);
if (visibility == View.VISIBLE || visibility == View.INVISIBLE || visibility == View.GONE) {
view.setVisibility(visibility);
}
return this;
}


}

第二个ViewHolder和第二个也有些区别是不是,区别是,又将setText和setImageBitmap的方法封装了一遍。这样一来,更疯狂,更方便。

使用例子:

public class ConvertAdapter extends CommonAdapter {
private Context context;

private List mDatas;

private ImageView ive;

public ConvertAdapter(Context context, List mDatas, int layoutId) {

super(context, mDatas, layoutId);

this.context = context;

this.mDatas = mDatas;
}

@Override
public void convertView(final int position, ViewHolder viewHolder, Object item) {
//如果要获取控件id就使用这个方式,但如果不需要,那就不用,text类型也是这样获取

// ive = = viewHolder.getView(R.id.ive);

//获取网络图片的方式
viewHolder.setImageBitmap(R.id.ive,bitmap/*这儿是bitmap类型的图片,要将url中的图片解析成bitmap类型,自己使用工具了*/);
//获取文本的方式
viewHolder.setText(R.id.tv_listview_item_game, mDatas.get(position).getName()); //JavaBean集合
//获取本地图片的方式
viewHolder.setImageResourse(R.id.ive, R.mipmap.heart_icon //这儿是本地图片id);
}

}
是不是很暴力,很疯狂,很简单,今后再也不用担心去写Adapter了,不过要是特别复杂的嘛,还是自己去写保险一点,以上两种方式的万能适配器直接复制可用,不用担心会出什么问题。因为我早就用在了项目中经久考验了,没问题。

对了,gridview也是类似的。我就不举例了哦。

封装的类就那点儿玩意儿,就不贴源码了。

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: