今天带来鸿洋大神的万能适配器实战。我们当然不想在项目中每个activity中遇到ListView、GridView就自定义个适配器。万能适配器可以帮我们减少代码的编写量,也能让项目更精炼!话不多说,如果你还没有使用万能适配器,那么赶紧的!
先上今天实现的效果图:
关键点:
1.ViewHolder类。利用SparseArray来存储布局中的每个view。主要方法:
get(Context context,View convertView,
ViewGroup parent,int layoutId,int position)getView(int viewId)
2.CommonAdapter类。利用泛型实现任何对象类型绑定。主要方法:
- convert(ViewHolder helper,T item)
下面给出项目具体实现,图片加载用的是Universal-ImageLoader开源框架,如果有同学感兴趣,可以看之前的一篇文章Universal-Image-Loader加载listView中图片
一.ViewHolder类。功能:
- 添加了setImageByUrl(int viewId,String url)方法,通过ImageLoader加载图片
- 这里其实可以实现我们在item中需要的很多方法
/**
* Created by ${wj} ,
* on 2015/7/6 0006.
*/
public class ViewHolder {
private SparseArray<View> mViews;//每个Item的view
private int mPosition;
private View mContentView;
private ImageLoader mImageLoader=ImageLoader.getInstance();
/**
* 构造器
* @param context
* @param parent
* @param layoutId
* @param position
*/
private ViewHolder(Context context,ViewGroup parent,int layoutId,int position){
this.mPosition=position;
this.mViews=new SparseArray<View>();
mContentView=LayoutInflater.from(context).inflate(layoutId,parent,false);
//setTag
mContentView.setTag(this);
}
/**
* 拿到一个ViewHolder对象
*/
public static ViewHolder get(Context context,View convertView,
ViewGroup parent,int layoutId,int position){
if(convertView==null){
return new ViewHolder(context,parent,layoutId,position);
}
return (ViewHolder) convertView.getTag();
}
/**
* 获取当前item对象
* @return
*/
public View getConvertView(){
return mContentView;
}
/**
* 通过控件的id获取对应的控件,如果没有则加入views
* @param viewId
* @param <T>
* @return
*/
public <T extends View> T getView(int viewId){
View view=mViews.get(viewId);//先从容器中获取
if(view==null){
view=mContentView.findViewById(viewId);
mViews.put(viewId,view);//放入容器中
}
return (T)view;
}
/**
* 为TextView设置字符串
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId,String text){
TextView view=getView(viewId);
view.setText(text);
return this;
}
/**
* 为ImageView设置图片
* @param viewId
* @param bm
* @return
*/
public ViewHolder setImageBitmap(int viewId,Bitmap bm){
ImageView iv=getView(viewId);
iv.setImageBitmap(bm);
return this;
}
/**
* 为ImageView设置图片(ImageLoader网络加载)
* @param viewId
* @param url
* @return
*/
public ViewHolder setImageByUrl(int viewId,String url){
/**
* ImageLoader 参数
*/
DisplayImageOptions options=new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.shishi)
.showImageForEmptyUri(R.drawable.shishi)
.cacheInMemory(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.displayer(new RoundedBitmapDisplayer(20))
.build();
mImageLoader.displayImage(url, (ImageView) getView(viewId),options);
return this;
}
/**
* 获取当前item角标
* @return
*/
public int getPosition(){
return mPosition;
}
}
二、CommonAdapter
其实主要方法就是对外开发的corvert方法
/**
* Created by ${wj} ,
* on 2015/7/6 0006.
*/
public abstract class CommonAdapter<T> extends BaseAdapter{
protected LayoutInflater mInflater;
protected Context mContext;
protected List<T> mDatas;//泛型list数据,可以适配所有对象类型
protected final int mItemLayoutId;
/**
* 构造器
* @param mDat需要显示的数据集合
* @param mCont上下文
* @param mItemLayoutI子布局文件
*/
public CommonAdapter(List<T> mDatas, Context mContext, int mItemLayoutId) {
this.mDatas = mDatas;
this.mContext = mContext;
this.mItemLayoutId = mItemLayoutId;
this.mInflater=LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public Object 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) {
final ViewHolder viewHolder=getViewHolder(position,convertView,parent);
convert(viewHolder,(T)getItem(position));
return viewHolder.getConvertView();
}
/**
* 抽取出getView中间改变的部分
* @param helper holder缓存对象
* @param item Bean对象
*/
public abstract void convert(ViewHolder helper,T item);
/**
* 根据我们的ViewHolder类,获取viewHolder对象
* @param position
* @param convertView
* @param parent
* @return
*/
private ViewHolder getViewHolder(int position,View convertView,ViewGroup parent){
return ViewHolder.get(mContext,convertView,parent,mItemLayoutId,position);
}
}
三、MainActivity中使用
private ListView strList;
private List<Star> mDatas=new ArrayList<>();
private CommonAdapter<Star> mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
strList= (ListView) findViewById(R.id.lv);
//初始化数据
initDatas();
//实例化万能适配器
mAdapter=new CommonAdapter<Star>(mDatas,getApplicationContext(),R.layout.item_3) {
@Override
public void convert(ViewHolder helper, Star item) {
helper.setText(R.id.item_name,item.getName());
helper.setText(R.id.item_describ,item.getDescrib());
helper.setImageByUrl(R.id.item_img,item.getImgUrl());
}
};
//listView绑定适配器
strList.setAdapter(mAdapter);
}
数据来源
private void initDatas()
{
Star star = null;
star = new Star("http://img0.imgtn.bdimg.com/it/u=1173327,3576718335&fm=11&gp=0.jpg",
"AngleBaby","跑男团一号美女AngleBaby!");
mDatas.add(star);
star = new Star("http://img4.imgtn.bdimg.com/it/u=1750535930,1467743570&fm=21&gp=0.jpg",
"邓超","跑男团老队长邓超!");
mDatas.add(star);
star = new Star("http://img5.imgtn.bdimg.com/it/u=1593808313,3868391842&fm=11&gp=0.jpg",
"包贝尔","跑男团光头包贝尔!");
mDatas.add(star);
star = new Star("http://img2.imgtn.bdimg.com/it/u=2037429927,1919504819&fm=21&gp=0.jpg",
"陈赫","跑男团一号贱男0.0陈赫!");
mDatas.add(star);
star = new Star("http://img2.imgtn.bdimg.com/it/u=3133077552,2769012996&fm=21&gp=0.jpg",
"王祖蓝","跑男团金老师王祖蓝!");
mDatas.add(star);
star = new Star("http://img2.imgtn.bdimg.com/it/u=2137668625,2504210993&fm=21&gp=0.jpg",
"郑凯","跑男团小猎豹郑凯!");
mDatas.add(star);
}
这里有一个简单的实体类Star
public class Star {
private String imgUrl;
private String name;
private String describ;
public Star(String imgUrl,String name,String describ) {
this.describ = describ;
this.imgUrl = imgUrl;
this.name = name;
}
public String getDescrib() {
return describ;
}
public void setDescrib(String describ) {
this.describ = describ;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
剩下的就是MyApplication中实例化ImageLoader,并且配置MainActivity的Application名字,网络加载权限。
/**
* Created by ${wj} on 2015/6/19 0019.
*/
public class MyApplication extends Application{
@Override
public void onCreate() {
super.onCreate();
//创建默认的ImageLoader参数
//ImageLoaderConfiguration configuration=ImageLoaderConfiguration.createDefault(this);
//创建可以打印log的ImageLoaderConfiguration
ImageLoaderConfiguration configuration=new ImageLoaderConfiguration.Builder(this)
.writeDebugLogs()
.memoryCache(new LruMemoryCache(2*1024*1024))//可以通过自己的内存缓存实现
.memoryCacheSize(2 * 1024 * 1024)//内存缓存的最大值
.memoryCacheSizePercentage(13)
.build();
//初始化ImageLoader
ImageLoader.getInstance().init(configuration);
}
}
OK,以上效果实现。需要源码的留言再贴吧,一般不需要了,哈哈!
Have a nice day!