在慕课网上学习到hyman老师的课程《打造万能适配器》,发现挺不错的,对于简化代码非常有效,在实际项目中非常有用。可惜没有提供源码。因此,依样画瓢编写了一遍代码,提供如下:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
public class ViewHolder {
private View convertView;
private SparseArray<View> views;//存放控件
private int position;
private ViewHolder(Context context,int position, ViewGroup parent,int layoutId){
this.position=position;
this.views =new SparseArray<View>();
this.convertView=LayoutInflater.from(context).inflate(layoutId, parent,false);
convertView.setTag(this);
}
/**
* 获得viewHolder
* @param context
* @param position
* @param convertView
* @param parent
* @param layoutId
* @return
*/
public static ViewHolder getViewHolder(Context context,int position, View convertView, ViewGroup parent,int layoutId){
if(convertView==null){
return new ViewHolder(context,position,parent,layoutId);
}else{
ViewHolder viewHolder=(ViewHolder) convertView.getTag();
//由于viewholder是复用的,因此需要修改position
viewHolder.position =position;
return viewHolder;
}
}
/**
* 获得控件
* @param viewId
* @return
*/
public <T extends View> T getView(int viewId){
View view=views.get(viewId);
if(view==null){
view=convertView.findViewById(viewId);
views.put(viewId, view);
}
return (T) view;
}
/**
* 获得convertView
* @return
*/
public View getConvertView(){
return convertView;
}
/**
* 获得position
* @return
*/
public int getPosition(){
return position;
}
//-------------------------TextView-----------------------
/**
* 设置TextView的内容
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId,String text){
TextView tv=getView(viewId);
tv.setText(text);
return this;
}
/**
* 设置TextView的内容
* @param viewId
* @param textId
* @return
* @throws Exception
*/
public ViewHolder setText(int viewId,int textId) {
//try{
TextView tv=getView(viewId);
tv.setText(textId);
//}catch(ClassCastException e){
// throw new Exception("类型转换错误,请确保传入的是TextView的viewId");
//}
return this;
}
/**
* 设置TextView的颜色
* @param viewId
* @param color
* @return
*/
public ViewHolder setTextColor(int viewId,int color){
TextView tv=getView(viewId);
tv.setTextColor(color);
return this;
}
//----------------------公共-----------------------
public ViewHolder setVisibility(int viewId,int visibility){
getView(viewId).setVisibility(visibility);
return this;
}
public ViewHolder setBackgroundResource(int viewId,int resid){
getView(viewId).setBackgroundResource(resid);
return this;
}
//----------------------ImageView-----------------------------
public ViewHolder setImageBitmap(int viewId,Bitmap bitmap){
ImageView iv=getView(viewId);
iv.setImageBitmap(bitmap);
return this;
}
public ViewHolder setImageDrawable(int viewId,Drawable drawable){
ImageView iv=getView(viewId);
iv.setImageDrawable(drawable);
return this;
}
public ViewHolder setImageResource(int viewId,int resourceId){
ImageView iv=getView(viewId);
iv.setImageResource(resourceId);
return this;
}
public ViewHolder setImageURI(int viewId,Uri uri){
ImageView iv=getView(viewId);
iv.setImageURI(uri);
return this;
}
/**
* 网络加载图片
* @param viewId
* @param uri 图片的网络地址
* @param defResourceId 默认显示的图片
* @return
*/
public ViewHolder displayImage(int viewId,String uri,int defResourceId){
ImageLoader.getInstance().displayImage(uri,(ImageView)getView(viewId), new DisplayImageOptions.Builder()
//.showImageOnLoading(R.drawable.common_img_loading) //加载显示的图片
.showImageForEmptyUri(defResourceId) //空uri
.showImageOnFail(defResourceId)//加载失败
.cacheInMemory(true)
.cacheOnDisk(true)
//.considerExifParams(true)
//.displayer(new RoundedBitmapDisplayer(20))//圆角
.build());
return this;
}
/**
* 网络加载图片
* @param viewId
* @param uri 图片的网络地址
* @param options
* @return
*/
public ViewHolder displayImage(int viewId,String uri,DisplayImageOptions options){
ImageLoader.getInstance().displayImage(uri,(ImageView)getView(viewId), options);
return this;
}
}
Apapter如下:
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
/**
* 通用Adapter
* 内部封装了ViewHolder,只需继承并实现抽象方法即可
* @author HWJ
*
* @param <T>
*/
public abstract class CommonAdapter<T> extends BaseAdapter {
protected List<T> list;
protected Context context;
protected int layoutId;
public CommonAdapter(Context context,List<T> list,int layoutId){
this.context=context;
this.list=list;
this.layoutId=layoutId;
}
@Override
public int getCount() {
return list.size();
}
@Override
public T getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder=ViewHolder.getViewHolder(context, position, convertView, parent, layoutId);
convert(viewHolder, getItem(position));
return viewHolder.getConvertView();
}
/**
* 设置控件的显示内容
* @param holder
* @param t
*/
public abstract void convert(ViewHolder viewHolder,T t) ;
}
其中ViewHolder中的ImageView使用了开源项目ImageLoader,实际中应该根据自己需求去实现,这里由于代码不完整,所以ViewHolder中的displayImage方法不能直接使用,直接删除就行。
这两个类对于多次使用到Adapter的地方非常有用,其中的实现思路绝对值得借鉴,再次感谢慕课网和hyman老师。