安卓开发 第七篇 我的安卓应用架构设计-----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

时间: 2024-08-27 15:40:21

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

安卓开发 第八篇 我的安卓应用架构设计-----图片选择以及剪裁

Android开发中遇到要从相册选择图片时,大多数人都会选择调用Android自带的相册,毕竟这样可以节约时间,又不用自己去处理图片的问题,不过这样也会产生一些问题,有些系统自带的相册真的是丑到没朋友,有时调用系统相册时不时的还可能发生崩溃问题.而我的安卓架构中选择了自定义相册的功能,其效果是仿照QQ的图片选择样式,通过dialog展现出来的,还自定义了图片的剪裁,使用了CropImageView 实现了多种剪裁效果. 图片选择的直接辅助类: /** * 图片选择辅助类 * Created by

安卓开发基础知识1(双摄像头安卓手机)

需求说明:安卓开发 内容       :双摄像头安卓手机调研 来自       :时间的诗 原文:http://mobile.163.com/16/0301/06/BH28BP9I001117A8_all.html# 有一句老话叫"人往高处走,水往低处流",世事万变,很多东西都在朝着更高一级的方向发展.手机行业也是如此,层出不穷的技术,让我们的智能机机身更薄.性能更强.功能更丰富等等,而时下非常火热的手机拍照也是被广大厂商所重视,摄像头像素越来越高,光学防抖.相位对焦等技术相继应用其中

安卓开发与分析者的利器--安卓右键工具

安卓右键工具,集成dex转jar,二进制xml查看,apk相关信息查询,apk图标提取,apk优化,手机屏幕截图,安装卸载,签名,反编译和回编译等功能,方便快捷,开发者们的利器. 下载地址:安卓右键工具. 运行环境为Windows,以下均以Windows环境下描述. 安卓右键工具运行环境 1.windows x86或者windows x64操作系统. 2.需安装android sdk,并配置adb环境变量. 3.需安装python,并配置python环境变量. 安卓右键工具功能说明 安卓右键工具

升讯威微信营销系统开发实践:(2)功能设计与架构设计

微信开发系列教程,将以一个实际的微信平台项目为案例,深入浅出的讲解微信开发.应用各环节的实现方案和技术细节. 本系列教程的最终目标是完成一个功能完善并达到高可用性能指标的微信管理软件,所以除了与微信本身紧密相关的对接和应用技术,还会讲到其它相关的所有知识点,从技术选型,架构设计,数据层的设计,API的设计,数据传输协议的设计,再到细节的前端的设计及技术应用,后台开发中的各方面技术,都会涉及.同时,在架构设计中,会考虑到运维领域的诸多问题,会涉及到部署环节中负载均衡及CDN分发,服务器流量及带宽控

安卓开发复习笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)

记得之前写过2篇关于底部菜单的实现,由于使用的是过时的TabHost类,虽然一样可以实现我们想要的效果,但作为学习,还是需要来了解下这个新引入类FragmentTabHost 之前2篇文章的链接: 安卓开发复习笔记——TabHost组件(一)(实现底部菜单导航) 安卓开发复习笔记——TabHost组件(二)(实现底部菜单导航) 关于Fragment类在之前的安卓开发复习笔记——Fragment+ViewPager组件(高仿微信界面)也介绍过,这里就不再重复阐述了. 国际惯例,先来张效果图: 下面

程序员带你学习安卓开发,十天快速入门-基础知识(四)

关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到熟悉的效果. 本系列课程是.Net程序员学习安卓开发系列课程. 下面是前三次课程列表: 程序员带你学习安卓开发,十天快速入门-安卓学习必要性 程序员带你学习安卓开发,十天快速入门-开发工具配置学习 程序员带你学习安卓开发,十天快速入-对比C#学习java语法 为了大家系统有效的快速入门安卓开发,推荐

安卓开发学习笔记-安卓开发之环境配置

作为一个工作了五年左右的C#资深开发程序员,虽然知道现在开始学安卓开发有点半路出家的味道,但是俗话说技多不压身,由于大学期间学习了java这门语言,而安卓开发又是以java作为开发语言,所以我感觉自己可以稍微涉足安卓,不求涉深,只求能懂,当然如果能有小成,也是我所希冀的. 要想学习安卓开发,首先肯定是配置安卓开发环境,安卓开发不像是asp.net或者winfrom.mvc之类的,直接安装完一个vs了事,然后你就可以大行其道的进行基于C#语言的项目开发了,搭建安卓开发环境,首先我们需要安装java

北京安卓开发培训班

兄弟连IT教育- www.itxdl.cn 免费自学教程领取- http://www.hdb.com/party/v7m3u.html 安卓开发市场的火爆与人才缺口形成巨大反差,催生了大量安卓培训班.但并不是说从安卓开发培训机班出来,就能成为安卓开发人才,就能赢得企业青睐.事实上,安卓开发培训班那么多,要选就选最好的. 那么,如何看安卓开发培训班强不强?专家说,主要从三个方面来考量: 行业地位 行业地位是技术实力的体现.一般来说,行业地位高,技术实力就越强,学员能学到的就更多,就业也就更容易拿高

安卓开发前的准备工作

安卓手机全球市场份额已经接近85%,成为了无处不在无所不能覆盖面最广的手机操作系统,所以我对安卓的学习也充满了信心,它终将成为自己的一技之长. 首先我们对Java和C++已经有了基础性的学习,具备了染指安卓开发的能力.在接触安卓前应该去复习更多的关于Java的知识.安卓的界面布局是跟网页设计差不多还有安卓开发环境的搭载,目前用的最多的是Eclipse,安装eclipse之前要安装一些java的平台 ,在开发的时候要多练习和多问,里面有很多要学的. 在开始前需要具备一些要素: 1.1.JDK安装