可复用的自定义Adapter

public abstract class MyAdapter<T> extends BaseAdapter {

    private ArrayList<T> mData;
    private int mLayoutRes;           //布局id

    public MyAdapter() {
    }

    public MyAdapter(ArrayList<T> mData, int mLayoutRes) {
        this.mData = mData;
        this.mLayoutRes = mLayoutRes;
    }

    @Override
    public int getCount() {
        return mData != null ? mData.size() : 0;
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = ViewHolder.bind(parent.getContext(), convertView, parent, mLayoutRes
                , position);
        bindView(holder, getItem(position));
        return holder.getItemView();
    }

    public abstract void bindView(ViewHolder holder, T obj);

    //添加一个元素
    public void add(T data) {
        if (mData == null) {
            mData = new ArrayList<>();
        }
        mData.add(data);
        notifyDataSetChanged();
    }

    //往特定位置,添加一个元素
    public void add(int position, T data) {
        if (mData == null) {
            mData = new ArrayList<>();
        }
        mData.add(position, data);
        notifyDataSetChanged();
    }

    public void remove(T data) {
        if (mData != null) {
            mData.remove(data);
        }
        notifyDataSetChanged();
    }

    public void remove(int position) {
        if (mData != null) {
            mData.remove(position);
        }
        notifyDataSetChanged();
    }

    public void clear() {
        if (mData != null) {
            mData.clear();
        }
        notifyDataSetChanged();
    }

    public static class ViewHolder {

        private SparseArray<View> mViews;   //存储ListView 的 item中的View
        private View item;                  //存放convertView
        private int position;               //游标
        private Context context;            //Context上下文

        //构造方法,完成相关初始化
        private ViewHolder(Context context, ViewGroup parent, int layoutRes) {
            mViews = new SparseArray<>();
            this.context = context;
            View convertView = LayoutInflater.from(context).inflate(layoutRes, parent, false);
            convertView.setTag(this);
            item = convertView;
        }

        //绑定ViewHolder与item
        public static ViewHolder bind(Context context, View convertView, ViewGroup parent,
                                      int layoutRes, int position) {
            ViewHolder holder;
            if (convertView == null) {
                holder = new ViewHolder(context, parent, layoutRes);
            } else {
                holder = (ViewHolder) convertView.getTag();
                holder.item = convertView;
            }
            holder.position = position;
            return holder;
        }

        @SuppressWarnings("unchecked")
        public <T extends View> T getView(int id) {
            T t = (T) mViews.get(id);
            if (t == null) {
                t = (T) item.findViewById(id);
                mViews.put(id, t);
            }
            return t;
        }

        /**
         * 获取当前条目
         */
        public View getItemView() {
            return item;
        }

        /**
         * 获取条目位置
         */
        public int getItemPosition() {
            return position;
        }

        /**
         * 设置文字
         */
        public ViewHolder setText(int id, CharSequence text) {
            View view = getView(id);
            if (view instanceof TextView) {
                ((TextView) view).setText(text);
            }
            return this;
        }

        /**
         * 设置图片
         */
        public ViewHolder setImageResource(int id, int drawableRes) {
            View view = getView(id);
            if (view instanceof ImageView) {
                ((ImageView) view).setImageResource(drawableRes);
            } else {
                view.setBackgroundResource(drawableRes);
            }
            return this;
        }

        /**
         * 设置点击监听
         */
        public ViewHolder setOnClickListener(int id, View.OnClickListener listener) {
            getView(id).setOnClickListener(listener);
            return this;
        }

        /**
         * 设置可见
         */
        public ViewHolder setVisibility(int id, int visible) {
            getView(id).setVisibility(visible);
            return this;
        }

        /**
         * 设置标签
         */
        public ViewHolder setTag(int id, Object obj) {
            getView(id).setTag(obj);
            return this;
        }

        //其他方法可自行扩展

    }

}
时间: 2024-10-11 11:27:37

可复用的自定义Adapter的相关文章

Android学习笔记-构建一个可复用的自定义BaseAdapter

转载自http://www.runoob.com/w3cnote/android-tutorial-customer-baseadapter.html   作者:coder-pig 本节引言: 如题,本节给大家带来的是构建一个可复用的自定义BaseAdapter,我们每每涉及到ListView GridView等其他的Adapter控件,都需要自己另外写一个BaseAdapter类,这样显得非常麻烦, 又比如,我们想在一个界面显示两个ListView的话,我们也是需要些两个BaseAdapter

自定义ListView实现中间项动态变大的效果(不是自定义Adapter)

为什么强调不是自定义Adapter,因为我这个自定义控件是来源与公司新做的项目,刚开始在百度上找了一圈,都说是自定义ListView ,点进去却是自定义Adaper,有的人就会说你是不是太较真了,自定义Adapter就基本可以实现各种效果了,何必要自定义Listview,今天我做的这个还确实不好用Adapter做,先上效果图,右边的动图来源于左边这个项目中的一个控件. 因为我们的项目中,六个通道的检测过程要同时动态显示,这样位置就要合理调配,因为六个通道采用的布局比较相似,所以当时考虑了Frag

自定义Adapter为什么会重复多轮调用getView?——原来是ListView.onMeasure在作祟

相信很多人在使用自定义Adapter的时候都遇到这样的问题: 假设Adapter数据源中只有30个Item,理论上每显示一个新的Item的时候就会调用一次getView,均显示一次的话是要调用getView() 30次的,然而当我们在getView输出Log信息时,前几个会被重复多轮调用,之后每滑动到一个新的Item便会正常调用getView? 针对这个问题,网上很多帖子指明这与ListView的Item的高度计算方法有关,并强调解决该问题的办法是在XML文件里面定义listView的时候需要设

Android基础入门教程——2.4.7 构建一个可复用的自定义BaseAdapter

Android基础入门教程--2.4.7 构建一个可复用的自定义BaseAdapter 标签(空格分隔): Android基础入门教程 本节引言: 如题,本节给大家带来的是构建一个可复用的自定义BaseAdapter,我们每每涉及到ListView GridView等其他的Adapter控件,都需要自己另外写一个BaseAdapter类,这样显得非常麻烦, 又比如,我们想在一个界面显示两个ListView的话,我们也是需要些两个BaseAdapter- 这,程序员都是喜欢偷懒的哈,这节我们就来写

封装能重用的自定义Adapter,向翔哥致敬

看了翔哥的自定义万能的adapter,自己也做下笔记,分析一下高手的思维方式,让我们一起进入变态程序员的内心世界. 分析万能的adapter之前,我们先分析一下普通的adapter public class ReportSpinnerAdapter extends BaseAdapter { private Context context; private List<String> str; public ReportSpinnerAdapter(Context context, List&l

【转】Android中Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现)

原文网址:http://embed.21ic.com/software/android/201403/31603.html 1 :Android中Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现) . 今天学习了Spinner组件,使用Spinner相当于从下拉列表中选择项目,下面演示一下Spinner的使用(分别使用ArrayAdapter和自定义Adapter实现) (一):使用ArrayAdapter进行适配数据: ①:首先定义一个布局文件: android:

【Android UI】ListView系列二(自定义Adapter订阅新闻栏目)

目标:自定义适配器Adapter实现点击每个item订阅按钮 上一篇介绍了listview的基本属性以及ArrayAdapter和SimpleAdapter的简单实用,链接:listview使用方式基础篇. 今天主要介绍一下自定义adapter,来实现稍微复杂点的功能,今天实现的效果是:类似于listiew展示许多可供订阅的栏目,每个栏目最右端有订阅按钮,用户点击订阅可以订阅该栏目,再次点击可取消订阅,效果图如下,下面我们一步步来实现. 1. 定义主布局文件activity_main.xml 主

自定义Adapter中实现startActivityForResult的分析

最近几天在做文件上传的时候,想在自定义Adapter中启动activity时也返回Intent数据,于是想到了用startActivityForResult,可是用mContext怎么也调不出这个方法,只能调用startActivity这个方法,于是在网上搜一下,可以利用一个方式可以间接的解决这个问题,果断贴代码: Intent mIntent = new Intent(mContext,clazz);((Activity) mContext).startActivityForResult(mI

Android 自定义Adapter 但listview 只显示第一条数据

楼主让这个问题郁闷了一晚上.....在logcat里明明显示adapter的getview方法里的list大于一条数据 ,但posotion却一直是0.....运行后也只显示list[0]里面的数据....最后的最后原来错误出在布局文件上 我以前的是这样的; <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content" > <!-- listv