安卓开发 第七篇 我的安卓应用架构设计-----Adapter类及ViewHolder类

在Android开发中,对于AdapterView类型的控件,我们都需要通过适配器来给它设置数据,如果显示的内容比较简单,我们通常使用SimpleAdapter或者ArrayAdapter,而对于复杂多变的数据,我们一般使用自定义一个继承自BaseAdapter的Adapter来处理。为了itemview的复用,我们通常用一个Viewholder来包装itemview里面的控件。

在我的安卓架构中,使用BaseAbsListAdapter作为所有AbsListView的适配器的基类:

/** * BaseAbsListAdapter是所有AbsListView的适配器的基类 * Created by naivor on 16-4-12. */
public abstract class BaseAbsListAdapter<T,VH extends BaseViewHolder<T>> extends BaseAdapter {
    protected Context context;
    protected LayoutInflater inflater;

    protected List<T> itemDatas;

    private VH viewHolder;

    public BaseAbsListAdapter(Context context, LayoutInflater inflater) {
        this.context = context;
        this.inflater = inflater;

        itemDatas = new ArrayList<>();
    }

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

    @Override
    public T getItem(int position) {
        if (position<getCount()){
            return itemDatas.get(position);
        }

        return null;
    }

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

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

        if (convertView==null){
            viewHolder=onCreateViewHolder(parent,getItemViewType(position),inflater);
            convertView=viewHolder.getConvertView();
            convertView.setTag(viewHolder);
        }else {
            viewHolder= (VH) convertView.getTag();
        }

        viewHolder.loadDataToView(position,getItem(position));

        return convertView;
    }

    public abstract VH onCreateViewHolder(ViewGroup parent, int viewType, LayoutInflater inflater);

    /** * 判断数据是否为空 */
    public boolean isEmpty() {
        return itemDatas.isEmpty();
    }

    /** * 添加数据 */
    public void addItems(List<T> list) {
        if (list != null) {
            itemDatas.addAll(list);
            notifyDataSetChanged();
        }
    }

    /** * 替换数据 * * @param originItem * @param newItem */
    public void replaceItem(T originItem, T newItem) {
        if (itemDatas.contains(originItem)) {
            int position = itemDatas.indexOf(originItem);
            itemDatas.remove(position);
            itemDatas.add(position, newItem);

            notifyDataSetChanged();
        }
    }


    /** * 添加数据 */
    public void addItems(int position, List<T> list) {
        if (list != null) {
            itemDatas.addAll(position, list);
            notifyDataSetChanged();
        }
    }

    /** * 添加单个数据 */
    public void addItem(T item) {
        if (item != null) {
            itemDatas.add(item);
            notifyDataSetChanged();
        }
    }

    /** * 添加单个数据 */
    public void addItem(int position, T item) {
        if (item != null && position >= 0) {
            itemDatas.add(position, item);
            notifyDataSetChanged();
        }
    }

    /** * 删除数据 */
    public void removeItem(int position) {
        if (position >= 0 && position < getCount()) {

            itemDatas.remove(position);
            notifyDataSetChanged();
        }
    }

    /** * 删除数据 */
    public void removeItem(T data) {
        if (data != null && itemDatas.contains(data)) {

            itemDatas.remove(data);
            notifyDataSetChanged();
        }
    }

    /** * 设置新数据,原来的清空 */
    public void setItems(List<T> list) {
        if (list != null) {
            itemDatas.clear();

            itemDatas.addAll(list);

            notifyDataSetChanged();
        }

    }

    /** * 清空 */
    public void clearItems() {
        if (!isEmpty()) {
            itemDatas.clear();
            notifyDataSetChanged();
        }
    }

    public List<T> getDatas() {
        return itemDatas;
    }

}

BaseAbsListAdapter主要包含了一些对数据的操作,比如添加一条或多条数据,移除一条或多条数据,替换一条数据,清空数据等等。。。。。

而BaseViewHolder则是所有ViewHolder的基类:

/** * BaseViewHolder是所有ViewHolder的基类 * Created by naivor on 16-4-12. */
public abstract class BaseViewHolder<T> {
    protected Context context;
    protected BaseAbsListAdapter absListAdapter;

    protected View convertView;

    protected int position;
    protected T data;

    public BaseViewHolder(View convertView,BaseAbsListAdapter absListAdapter) {
        this.convertView = convertView;
        context=convertView.getContext();
        this.absListAdapter=absListAdapter;

    }

    public View getConvertView() {
        return convertView;
    }

    /** * 将ItemData加载到ItemView上面,在实际的Viewholder中,需要重写此方法 * * @param position * @param data * @return */
    public   void loadDataToView(int position, T data){
        this.position=position;
        this.data=data;
    }

    /** * 查找控件 * * @param viewId * @return */
    public View find(int viewId) {
        return convertView.findViewById(viewId);

    }

   /** * itemview子控件的点击事件的监听器 * */
    public static interface OnInnerViewClickListener<T> {
        public void onClick(View view, T itemData, int postition);
    }
}

BaseViewHolder则主要负责将itemData的数据加载到itemView上面,同时还可以通过实现View.OnClickListener,处理itemview内部的控件的点击事件。

好了,就到这里吧!

如果有更深的理解,本文将会修改;
如果有错误的地方,欢迎指正;
如果你有更好的理解,欢迎交流。

本文为原创文章,版权归博主所有,转载请注明出处。

更多资料:

我的github地址以及使用demo: https://github.com/naivor/naivorapp

你可能感兴趣的:(android,架构设计,Adapter,viewholder,listview优化)