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

Android万能适配器 简化繁琐的开发

2016-02-23 09:32 597 查看
Android万能适配器 简化繁琐的开发

原文链接:http://mp.weixin.qq.com/s?__biz=MzA3MzE2MjgyMQ==&mid=401228643&idx=1&sn=e57d8e448411b40b46b25ea0e1446b42&scene=0#wechat_redirect

2016-01-12 威哥干Java

威哥干Java(weige-java)——不一样的技术分享,不一样的学习体验,跟威哥一起学Java,你一定可以!登录 http://www.codingke.com,更有C、C++、iOS、Android、Cocos2d-x、Swift课程免费看,我在扣丁学堂,你——在哪里?

项目中Listview GridView几乎是必用的组件,Android也提供一套机制,为这些控件绑定数据,那就是Adapter。用起来虽然还不错,但每次都需要去继承一个BaseAdapter,然后实现里面的一大堆方法,而我们每次最关心的无非就是getView方法,其余的方法几乎都是相同代码。这里是不是就可以优化起来呢?在其次,我们在使用Adapter的时候,为了优化性能,常常会创建一个Holder。而Holder里面每次存放的都是View,对Holer的操作无非也就是初始化,绑定数据,复用。这里是不是也可以抽取抽取? 好了,废话不多说,直接上代码。

首先第一步操作BaseAdapter公共部分抽取:

/**
* 万能适配器
* @param <T> 数据源的数据类型
*/
public abstract class CommonAdapter<T> extends BaseAdapter {
protected Context mContext; //上下文;
protected List<T> listDatas;//数据源;
protected int layoutId;     //Item布局ID;

{
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
{
return position;
}

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

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

}
第二步Holer的通用化

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

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

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

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
*/
@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
*/
public View getMConvertView()
{
return mConvertView;
}
}
第三步使用

public class VolTeamAdapter extends CommonAdapter<Bean>
{
public VolTeamAdapter(Context context, List<Bean> listDatas,int layoutId)
{
super(context, listDatas, layoutId);
}

@Override
{
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());
}
}


到这里 万事大吉,以后每次写Adaper的时候,无论你的Item布局怎么样,只需要重写一个方法绑定你的数据就OK,能节约不少开发时间。

威哥说:

每次重复写大概一样的适配器代码和ViewHolder,是时候要改造一下了,以上的代码你学会了吗,其实也不难理解,如果你看过扣丁Java面向对象中讲解模板方法设计模式的视频,你会很快明白,这里就是用的这个设计模式,把fillData方法延迟到子类中实现。至于这个通用的ViewHolder,大家可以改成自己的,或直接拿来用就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: