打造万能适配器 (80行-25行代码)极限优化

2015-12-17  本文已影响208人  sherlock221b
极限.jpg

android中像是ListView和girdview 这种组件在项目中使用频率非常高, adapter 也是每次必写的玩意 合理的封装 优化 可以使得我们的写更少的代码 做更多的事情.

以下文章阐述了如何从80行代码 优化到 25行

ViewHolder 优化

传统的ViewHolder 一般都在自定义的adapter去编写,并且每一个adapter都会对应一个自定义的内部类viewholder.

MyAdapter 中 viewHolder 部分代码:
<pre>
private class ViewHolder{

    TextView  userName;
    TextView  userAge;
    TextView  userAddress;
}

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

    ViewHolder holder;
    if(convertView == null){
        convertView = mInflater.inflate(this.layout,parent,false);
        holder = new ViewHolder();

        holder.userName = (TextView) convertView.findViewById(R.id.user_name);
        holder.userAge = (TextView) convertView.findViewById(R.id.user_age);
        holder.userAddress = (TextView) convertView.findViewById(R.id.user_address);

        convertView.setTag(holder);
    }
    else{
        holder = (ViewHolder) convertView.getTag();
    }

    return convertView;
}

</pre>

优化方案 : 将各零散 viewHolder 抽象成一个通用类 适配所有自定义的adapter 并且viewHolder的相关业务 从adapter中 放到 通用viewHolder中.

抽象之后 使用通用viewHolder <b>1</b>行代码
<pre>

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = ViewHolder.get(context, convertView, parent, position, layout);
return viewHolder.getConvertView();
}

</pre>

获得控件我们就可以用通用类中封装好的方法getView(int id)
<pre>
TextView textView = viewHolder.getView(R.id.user_name);
</pre>

以下 ViewHolder 公共类 :
<pre>
/**

/**
 * 取得viewholder存储的的控件
 * @param viewId
 * @param <T>
 * @return
 */
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;
}

}

</pre>

Adapter优化

我们建立一个CommonAdapter 继承自BaseAdapter

<pre>

public abstract class CommonAdapter<T> extends BaseAdapter {

protected LayoutInflater mInflater;
protected int layout;
protected Context context;
protected List<T> dataList;

public CommonAdapter(Context context, int layout, List<T> dataList) {
    this.context = context;
    this.layout = layout;
    this.dataList = dataList;
    this.mInflater.from(context);
}

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

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

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

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

}

</pre>

使用commonAdapter,代码是不是精简很多 我们还可以继续优化:
<pre>
public class MyAdapter extends CommonAdapter<User> {

public MyAdapter(Context context, int layout,List<User> dataList) {
    super(context,layout,dataList);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder = ViewHolder.get(context, convertView, parent, position, layout);
    //使用
    TextView textView = viewHolder.getView(R.id.user_name);
    return viewHolder.getConvertView();
}

}

</pre>

我可以做到让使用者更加专注他们的业务, 可以将
ViewHolder viewHolder = ViewHolder.get(context, convertView, parent, position, layout);
return viewHolder.getConvertView();
两部分代码 继续封装 复用

在CommonAdapter中加入 一个抽象方法
public abstract void convert(ViewHolder holder,T t);
在commonAdapter中实现getView
<pre>

@Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder viewHolder = ViewHolder.get(context, convertView, parent, position, layout);
convert(viewHolder,getItem(position));
return viewHolder.getConvertView();
}
</pre>

我们的MyAdapter来实现convert 这个部分就是暴露给 使用者的部分 在这里可以拿到一个holde如和 对应业务bean的俩个对象 让你专注填业务

超级清爽
<pre>
public class MyAdapter extends CommonAdapter<User> {

public MyAdapter(Context context, int layout,List<User> dataList) {
    super(context,layout,dataList);
}

@Override
public void convert(ViewHolder holder, User user) {
    //使用
    TextView textView = holder.getView(R.id.user_name);
    textView.setText(user.getUserName());
}

}
</pre>

极限优化 1行代码

我们可以通过链式调用来实现这个效果,我们在ViewHolder中 写2个辅助方法

<pre>
public ViewHolder setText(int viewId,String text){
TextView textView = getView(viewId);
textView.setText(text);
return this;
}

public ViewHolder setImageResource(int viewId,int resId){
ImageView imageView = getView(viewId);
imageView.setImageResource(resId);
return this;
}
</pre>

可以根据你的控件情况 来封装不同的方法.

使用起来很easy了 呵呵 真的一行足矣
<pre>

public class MyAdapter extends CommonAdapter<User> {

public MyAdapter(Context context, int layout, List<User> dataList) {
    super(context, layout, dataList);
}

@Override
public void convert(ViewHolder holder, User user) {
    holder  .setText(R.id.user_name, user.getUserName())
            .setText(R.id.user_age, user.getUserAge())
            .setText(R.id.user_address, user.getUserAddress());

}

}
</pre>

上一篇下一篇

猜你喜欢

热点阅读