zoukankan      html  css  js  c++  java
  • Adapter ViewHolder 封装实践

    尝试Android中ViewHolder模式进行封装的实践

    提供一个ViewHolder接口,约定其实现类具有一个以View为参数的构造器,构造器中写各种findViewById。接口方法bindItem提供将item显示到View的方法。

    对Adapter以及ArrayAdapter作出扩展,简化关于View回收判断部分的代码。

    以下为具体实现。

    package com.zwb.commonlibs.adapters;
    
    /**
     * 为{@link ArrayViewHolderAdapter}及{@link ViewHolderAdapter}提供ViewHolder,
     * 提供从convertView生成ViewHolder的构造器和从item生成视图的方法
     *
     * @author zwb
     */
    public interface ViewHolder {
    
        /**
         * 由item生成视图
         *
         * @param o     传入的item
         * @param position adapter中的位置
         */
        void bindItem(Object o, int position);
    }
    
    package com.zwb.commonlibs.adapters;
    
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    
    import java.lang.reflect.Constructor;
    
    /**
     * 使用{@link ViewHolder}的{@link BaseAdapter}
     */
    public abstract class ViewHolderAdapter extends BaseAdapter {
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        protected abstract int getResId(int viewType);
    
        protected abstract Class<? extends ViewHolder> getViewHolderClass(int viewType);
    
        @Override
        public final View getView(int position, View convertView, ViewGroup parent) {
            int viewType = getItemViewType(position);
            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext()).inflate(getResId(viewType), parent, false);
                try {
                    Constructor<? extends ViewHolder> constructor = getViewHolderClass(viewType).getConstructor(View.class);
                    ViewHolder viewHolder = constructor.newInstance(convertView);
                    convertView.setTag(viewHolder);
                } catch (Exception e) {
                    throw new RuntimeException("ViewHolder必须有一个View参数的构造器");
                }
            }
            //noinspection unchecked
            ViewHolder viewHolder = (ViewHolder) convertView.getTag();
            viewHolder.bindItem(getItem(position), position);
            return convertView;
        }
    }
    
    package com.zwb.commonlibs.adapters;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    
    import java.lang.reflect.Constructor;
    import java.util.List;
    
    /**
     * 使用{@link ViewHolder}的{@link ArrayAdapter}
     *
     * @param <T> 数据类型
     * @author zwb
     */
    public class ArrayViewHolderAdapter<T> extends ArrayAdapter<T> {
        protected LayoutInflater mLayoutInflater;
        private int mResource;
        private Constructor<? extends ViewHolder> mConstructor;
    
        public ArrayViewHolderAdapter(Context context, int resource, Class<? extends ViewHolder> class1) {
            super(context, 0);
            init(context, resource, class1);
        }
    
        public ArrayViewHolderAdapter(Context context, int resource, List<T> objects, Class<? extends ViewHolder> class1) {
            super(context, 0, objects);
            init(context, resource, class1);
        }
    
        private void init(Context context, int resource, Class<? extends ViewHolder> clazz) {
            mResource = resource;
            mLayoutInflater = LayoutInflater.from(context);
            try {
                mConstructor = clazz.getConstructor(View.class);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(clazz.getName() + " 必须带有View参数的构造器");
            }
        }
    
        @Override
        public final View getView(int position, View convert, ViewGroup parent) {
            ViewHolder viewHolder = null;
            if (convert == null) {
                convert = mLayoutInflater.inflate(mResource, parent, false);
                try {
                    viewHolder = mConstructor.newInstance(convert);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                convert.setTag(viewHolder);
            } else {
                //noinspection unchecked
                viewHolder = (ViewHolder) convert.getTag();
            }
            //noinspection ConstantConditions
            viewHolder.bindItem(getItem(position), position);
            return convert;
        }
    }

    以下为两个Demo

    使用ArrayViewHolderAdapter

        public class ViewHolderImpl implements ViewHolder {
            private final TextView name, time, code;
    
            public ViewHolderImpl(View view) {
                name = (TextView) view.findViewById(R.id.textName);
                time = (TextView) view.findViewById(R.id.textTime);
                code = (TextView) view.findViewById(R.id.textCode);
            }
    
            @Override
            public void bindItem(Object o, int position) {
                DataObject item = (DataObject) o;
                name.setText(item.getName());
                time.setText(item.getTime());
                code.setText(item.getCode());
            }
        }
    //创建Adapter
    ArrayAdapter<DataObject> adapter=new ArrayViewHolderAdapter<>(context,R.layout.data_object,ViewHolderImpl.class);

    使用ViewHolderAdapter

    public class ViewHolder1 implements ViewHolder{
        //实现同上
    }
    public class ViewHolder2 implements ViewHolder{
        //实现同上
    }
    public class MyAdapter extends ViewHolderAdapter{
        public Object getItem(int position){
            //TODO
    }

       public int getItemCount(){
         //TODO
       } public int getViewTypeCount(){ return 2; } public int getItemViewType(int position){ //TODO } public Class<? extends ViewHolder> getViewHolderClass(int viewType){ return viewType==0?ViewHolder1.class:ViewHolder2.class; } public int getResId(int viewType){ return viewType==0?R.layout.item1:R.layout.item2; } }



  • 相关阅读:
    php-基于面向对象的MySQL类
    php-迭代创建级联目录
    php-删除非空目录
    php-递归创建级联目录
    linux 用户管理
    mysql 语法大全
    dos命令下修改mysql密码的方法
    对 linux init.d的理解
    linux 重启服务器命令
    校验软件包
  • 原文地址:https://www.cnblogs.com/hqzxzwb/p/4908592.html
Copyright © 2011-2022 走看看