编辑
Android通用适配器。
本文访问次数:0
  1. 1. 说明
  2. 2. 什么是adapter
  3. 3. ButterKnife的好处
  4. 4. ViewHolder的使用
  5. 5. Model的使用
  6. 6. Adapter的写法

说明

我们都见过各种adapter了,虽然说开发规范里写着DRY,但是学习一下基础知识还是不错的
而且在开发手上的一个项目时发现github上的一些adapter都不够符合业务需求,所以索性自己开发了一个通用adapter

什么是adapter

我认为adapter就是listviewgridview等列表的管理者,它负责提供数据和视图

ButterKnife的好处

经常看见各种adapter里都写了findViewByID的辅助方法,方便对item进行视图绑定,我推荐使用ButterKnife进行这个操作,没有必要单独写个方法
而且是自己的项目,确定已经引入了ButterKnife包。所以这个adpter的使用前提是项目引入了ButterKnife包。

ViewHolder的使用

接着说视图绑定,为了使代码更简洁有序,我使用了ButterKnifeViewHolder,简单来说ViewHolder维护了一些视图的引用,方便adpter对视图进行
个性化操作,如设置文本内容、颜色或其他属性。以下为CommonViewHolder的关键代码

/**
 * Created by zongren on 16/5/4.
 */
public abstract class CommonViewHolder {
    private View mView;

    public CommonViewHolder() {

    }

    public CommonViewHolder(View view) {
        setView(view);
    }

    public View getView() {
        return mView;
    }

    public void setView(View view) {
        mView = view;
        ButterKnife.bind(this, view);
    }

}

首先这个类是虚类,使用的时候需要继承它然后生成实例,我觉得必须这么设定,因为不同的ViewHolder肯定是绑定了不同的视图,没有必要做为实类
以下为使用例子

/**
 * Created by zongren on 16/5/13.
 */
public class CategoryViewHolder extends CommonViewHolder {
    @Bind(R.id.item_category_thumb_imageView)
    public ImageView thumbImageView;
    @Bind(R.id.item_category_title_textView)
    public TextView titleTextView;
}

我直接把thumbImageViewtitleTextView的属性设置为public,方便adapter对视图操作,也可以写单独的setter方法对它们进行操作

Model的使用

通常情况下,listViewitem都是比较丰富的,不只是简单的一个textView,那么就需要定义Model,方便管理数据。以下为CategoryModel的关键代码

/**
 * Created by zongren on 16/4/21.
 */
public class CategoryModel {
    private String mTitle;
    private String mCategoryId;
    private String mImageUrl;

    public CategoryModel(String title, String categoryId) {
        mTitle = title;
        mCategoryId = categoryId;
    }

    public String getTitle() {
        return mTitle;
    }

    public void setTitle(String title) {
        this.mTitle = mTitle;
    }

    public String getCategoryId() {
        return mCategoryId;
    }

    public void setCategoryId(String categoryId) {
        this.mCategoryId = mCategoryId;
    }

    public String getImageUrl() {
        return mImageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.mImageUrl = mImageUrl;
    }

    @Override
    public String toString() {
        return mTitle;
    }
}

Adapter的写法

以上介绍了Adapter用到的若干个元素,现在说一下本体的写法,关键代码如下:


/**
 * Created by zongren on 16/5/4.
 */
public abstract class CommonAdapter<T, V extends CommonViewHolder> extends BaseAdapter {
    private static final String TAG = "CommonAdapter";
    protected List<T> mData;
    protected int mItemLayoutId;
    private Context mContext;

    public CommonAdapter(Context context, int itemLayoutId, List<T> data) {
        super();
        mContext = context;
        mItemLayoutId = itemLayoutId;
        mData = data;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup container) {
        if (convertView == null) {
            convertView = inflateView(position, container, false);
            V viewHolder = getViewHolder();
            viewHolder.setView(convertView);
            convertView.setTag(viewHolder);
        }
        V viewHolder = (V) convertView.getTag();
        convertView(viewHolder, mData.get(position));
        return convertView;
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

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

    protected View inflateView(int position, ViewGroup container, boolean attach) {
        return LayoutInflater.from(mContext).inflate(mItemLayoutId, container, attach);
    }

    public abstract V getViewHolder();

    public abstract void convertView(V viewHolder, T data);

    public List<T> getData() {
        return mData;
    }

    public void setData(List<T> data) {
        mData = data;
    }
}

可以看到,我同样把adapter设置成了虚类,原因和ViewHolder设置为虚类一样,不再赘述。T表示Model的类型,V表示ViewHolder的类型,这两个要在声明adapter的使用提供
protected View inflateView(ViewGroup container, boolean attach)方法是用来渲染每个item的视图的,如果item的样式是不固定的,可以在实体类中重写这个方法,例如

@Override
protected View inflateView(int position, ViewGroup container, boolean attach) {
    return LayoutInflater.from(mContext).inflate(mLayouts.get(position), container, attach);
}

public abstract V getViewHolder()是一个需要实现的方法,用来提供V类型的ViewHolder
public abstract void convertView(V viewHolder, T data);是另外一个需要实现的方法,用来对viewHolder中的视图进行个性化更改

以下为CommonAdapter的具体使用,TCategoryModelVCategoryViewHolder

new CommonAdapter<CategoryModel, CategoryViewHolder>(getContext(), R.layout.item_category, mLevelTwoCategories) {
    @Override
    public CategoryViewHolder getViewHolder() {
        return new CategoryViewHolder();
    }

    @Override
    public void convertView(CategoryViewHolder viewHolder, CategoryModel data) {
        viewHolder.titleTextView.setText(data.getTitle());
    }
};
没有任何评论