今天随便逛逛CSDN,看到主页上推荐了一篇文章Android 高速开发系列 打造万能的ListView GridView 适配器,刚好这两天写项目自己也封装了相似的CommonAdapter,曾经也在github上看到过这种库,于是自己也把自己的代码再次整理出来与大家分享,也希望可以在CSDN这个平台上学到很多其它的东西,以下就一起来看看吧。

平时我们在项目中使用到ListView和GridView组件都是都会用到Adapter,比較多的情况是继承自BaseAdapter,然后实现getCount、getView等方法,再使用ViewHolder来提高一下效率.我们看以下一个简单的样例 :

ListView布局文件

fragment_main.xml :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.example.push_demo_1.MainActivity$PlaceholderFragment" ><ListViewandroid:id="@+id/my_listview"android:layout_width="match_parent"android:layout_height="match_parent" /></RelativeLayout>

ListView子项的布局文件

listview_item_layout.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal" ><ImageViewandroid:id="@+id/my_imageview"android:layout_width="64dp"android:layout_height="64dp"android:contentDescription="@string/app_name" /><TextViewandroid:id="@+id/my_textview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:textSize="18sp" /></LinearLayout>

曾经我们要写下的Adapter代码

public class NormalAdapter extends BaseAdapter {Context mContext;LayoutInflater mInflater;List<ListViewItem> mDataList;/*** @param context* @param data*/public NormalAdapter(Context context, List<ListViewItem> data) {mContext = context;mInflater = LayoutInflater.from(context);mDataList = data;}@Overridepublic int getCount() {return mDataList.size();}@Overridepublic ListViewItem getItem(int position) {return mDataList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder = null;if (convertView == null) {convertView = mInflater.inflate(R.layout.listview_item_layout, null, false);viewHolder = new ViewHolder();viewHolder.mImageView = (ImageView) convertView.findViewById(R.id.my_imageview);viewHolder.mTextView = (TextView) convertView.findViewById(R.id.my_textview);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}viewHolder.mImageView.setImageResource(getItem(position).mDrawableId);viewHolder.mTextView.setText(getItem(position).mText);return convertView;}/*** ViewHolder* * @author mrsimple*/static class ViewHolder {ImageView mImageView;TextView mTextView;}}

然而写过多遍以后我们发现我们总是反复地在写这些getCount、getItem、getView方法以及ViewHolder,导致了非常多反复工作,而且及其无聊,于是我把这些反复工作抽象起来(曾经也有在github上看到这种通用Adapter实现),整理一下也便于自己使用,也是自己学习的一个过程。以下我们看看使用CommonAdapter后我们做与上面相同的工作须要怎么写。

使用CommonAdapter后要写的代码

CommonAdapter<ListViewItem> listAdapter = new CommonAdapter<ListViewItem>(getActivity(),R.layout.listview_item_layout, mockListViewItems()) {@Overrideprotected void fillItemData(CommonViewHolder viewHolder, ListViewItem item) {// 设置图片viewHolder.setImageForView(R.id.my_imageview, item.mDrawableId);// 设置textviewHolder.setTextForTextView(R.id.my_textview, item.mText);}}

当中mockListViewImtes是准备了一些数据, 代码例如以下 :

        /*** 模拟一些数据* * @return*/private List<ListViewItem> mockListViewItems() {List<ListViewItem> dataItems = new ArrayList<ListViewItem>();dataItems.add(new ListViewItem(R.drawable.girl_96, "girl_96.png"));dataItems.add(new ListViewItem(R.drawable.fire_96, "fire_96.png"));dataItems.add(new ListViewItem(R.drawable.grimace_96, "grimace_96.png"));dataItems.add(new ListViewItem(R.drawable.laugh_96, "laugh_96.png"));return dataItems;}

可以看到,我们的代码量降低了非常多,假设一个项目中有好几个ListView、GridView等组件,我们就不须要反复做那么多无聊的工作了。我们看看效果图 :

CommonAdapter实现

/**** created by Mr.Simple, Aug 28, 201412:26:52 PM.* Copyright (c) 2014, hehonghui@umeng.com All Rights Reserved.**                #####################################################*                #                                                   #*                #                       _oo0oo_                     #   *                #                      o8888888o                    #*                #                      88" . "88                    #*                #                      (| -_- |)                    #*                #                      0\  =  /0                    #   *                #                    ___/`---'\___                  #*                #                  .' \\|     |# '.                 #*                #                 / \\|||  :  |||# \                #*                #                / _||||| -:- |||||- \              #*                #               |   | \\\  -  #/ |   |              #*                #               | \_|  ''\---/''  |_/ |             #*                #               \  .-\__  '-'  ___/-. /             #*                #             ___'. .'  /--.--\  `. .'___           #*                #          ."" '<  `.___\_<|>_/___.' >' "".         #*                #         | | :  `- \`.;`\ _ /`;.`/ - ` : | |       #*                #         \  \ `_.   \_ __\ /__ _/   .-` /  /       #*                #     =====`-.____`.___ \_____/___.-`___.-'=====    #*                #                       `=---='                     #*                #     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   #*                #                                                   #*                #               佛祖保佑         永无BUG              #*                #                                                   #*                #####################################################*/package com.uit.commons;import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;import java.util.List;/*** 这是一个通用、抽象的适配器类,覆写了BaseAdapter的getCount, getItem, getItemId,* getView方法,在getView方法中通过* 通用的CommonViewHolder来对convertView的进行处理,而且缓存convertView中的其它View元素* ,降低了ListView、GridView 等组件的Adapter和ViewHolder的代码量.* 用户仅仅须要在fillItemData函数中将第position位置里的数据填充到listview或者gridview的第position的view中就可以* ,详细使用实例參考文档.* * @author mrsimple* @param <T> 数据源的类型*/
public abstract class CommonAdapter<T> extends BaseAdapter {/*** Context*/Context mContext;/*** 要展示的数据列表*/List<T> mData;/*** 每一项的布局id,比如R.layout.my_listview_item.*/private int mItemLayoutId = -1;/*** @param context Context* @param itemLayoutResId*            每一项(适用于listview、gridview等AbsListView子类)的布局资源id,比如R.layout.*            my_listview_item.* @param dataSource 数据源*/public CommonAdapter(Context context, int itemLayoutResId, List<T> dataSource) {checkParams(context, itemLayoutResId, dataSource);mContext = context;mItemLayoutId = itemLayoutResId;mData = dataSource;}/*** 检查參数的有效性* * @param context* @param itemLayoutResId* @param dataSource*/private void checkParams(Context context, int itemLayoutResId, List<T> dataSource) {if (context == null || itemLayoutResId < 0 || dataSource == null) {throw new RuntimeException("context == null || itemLayoutResId < 0 || dataSource == null, please check your params");}}/*** 返回数据的总数*/@Overridepublic int getCount() {return mData.size();}/*** 返回position位置的数据*/@Overridepublic T getItem(int position) {return mData.get(position);}/*** item id, 返回position*/@Overridepublic long getItemId(int position) {return position;}/*** 返回position位置的view, 即listview、gridview的第postion个view*/@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// 获取ViewHolderCommonViewHolder viewHolder = CommonViewHolder.getViewHolder(mContext, convertView,mItemLayoutId);// 填充数据fillItemData(viewHolder, getItem(position));// 返回convertviewreturn viewHolder.getConvertView();}/*** 用户必须覆写该方法来讲数据填充到视图中* * @param viewHolder 通用的ViewHolder, 里面会装载listview,*            gridview等组件的每一项的视图,而且缓存其子view* @param item 数据源的第position项数据*/protected abstract void fillItemData(CommonViewHolder viewHolder, T item);}

CommonViewHolder实现

/**** created by Mr.Simple, Aug 28, 201412:32:45 PM.* Copyright (c) 2014, hehonghui@umeng.com All Rights Reserved.**                #####################################################*                #                                                   #*                #                       _oo0oo_                     #   *                #                      o8888888o                    #*                #                      88" . "88                    #*                #                      (| -_- |)                    #*                #                      0\  =  /0                    #   *                #                    ___/`---'\___                  #*                #                  .' \\|     |# '.                 #*                #                 / \\|||  :  |||# \                #*                #                / _||||| -:- |||||- \              #*                #               |   | \\\  -  #/ |   |              #*                #               | \_|  ''\---/''  |_/ |             #*                #               \  .-\__  '-'  ___/-. /             #*                #             ___'. .'  /--.--\  `. .'___           #*                #          ."" '<  `.___\_<|>_/___.' >' "".         #*                #         | | :  `- \`.;`\ _ /`;.`/ - ` : | |       #*                #         \  \ `_.   \_ __\ /__ _/   .-` /  /       #*                #     =====`-.____`.___ \_____/___.-`___.-'=====    #*                #                       `=---='                     #*                #     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   #*                #                                                   #*                #               佛祖保佑         永无BUG              #*                #                                                   #*                #####################################################*/package com.uit.commons;import android.content.Context;
import android.graphics.Bitmap;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;import com.uit.commons.utils.ViewFinder;/*** 这是一个通用的ViewHolder, 将会装载AbsListView子类的item View, 而且将item* view中的子视图进行缓存和索引,使得用户可以方便的获取这些子view, 降低了代码反复。* * @author mrsimple*/
public class CommonViewHolder {/*** 构造函数* * @param context Context* @param layoutId ListView、GridView或者其它AbsListVew子类的 Item View的资源布局id*/protected CommonViewHolder(Context context, int layoutId) {// 初始化布局, 装载ContentViewViewFinder.initContentView(context, layoutId);// 将ViewHolder存储在ContentView的tag中ViewFinder.getContentView().setTag(this);}/*** 获取CommonViewHolder,当convertView为空的时候从布局xml装载item view,* 而且将该CommonViewHolder设置为convertView的tag, 便于复用convertView.* * @param context Context* @param convertView Item view* @param layoutId 布局资源id, 比如R.layout.my_listview_item.* @return 通用的CommonViewHolder实例*/public static CommonViewHolder getViewHolder(Context context, View convertView, int layoutId) {if (convertView == null) {return new CommonViewHolder(context, layoutId);}return (CommonViewHolder) convertView.getTag();}/*** @return 当前项的convertView, 在构造函数中装载*/public View getConvertView() {return ViewFinder.getContentView();}/*** 为id为textViewId的TextView设置文本内容* * @param textViewId 视图id* @param text 要设置的文本内容*/public void setTextForTextView(int textViewId, CharSequence text) {TextView textView = ViewFinder.findViewById(textViewId);if (textView != null) {textView.setText(text);}}/*** 为ImageView设置图片* * @param imageViewId ImageView的id, 比如R.id.my_imageview* @param drawableId Drawable图片的id, 比如R.drawable.my_photo*/public void setImageForView(int imageViewId, int drawableId) {ImageView imageView = ViewFinder.findViewById(imageViewId);if (imageView != null) {imageView.setImageResource(drawableId);}}/*** 为ImageView设置图片* * @param imageViewId ImageView的id, 比如R.id.my_imageview* @param bmp Bitmap图片*/public void setImageForView(int imageViewId, Bitmap bmp) {ImageView imageView = ViewFinder.findViewById(imageViewId);if (imageView != null) {imageView.setImageBitmap(bmp);}}/*** 为CheckBox设置是否选中* * @param checkViewId CheckBox的id* @param isCheck 是否选中*/public void setCheckForCheckBox(int checkViewId, boolean isCheck) {CheckBox checkBox = ViewFinder.findViewById(checkViewId);if (checkBox != null) {checkBox.setChecked(isCheck);}}
}

ViewFinder辅助类

/*** view finder, 方便查找View。用户须要在使用时调用initContentView,* 将Context和布局id传进来,然后使用findViewById来获取须要的view* ,findViewById为泛型方法,返回的view则直接是你接收的类型,而不须要进行强制类型转换.比方,* 曾经我们在Activity中找一个TextView通常是这样 : * TextView textView = (TextView)findViewById(viewId); * 假设页面中的控件比較多,就会有非常多的类型转换,而使用ViewFinder则免去了类型转换,* 示比例如以下 : * TextView textView = ViewFinder.findViewById(viewId);* * @author mrsimple*/
public final class ViewFinder {/*** LayoutInflater*/static LayoutInflater mInflater;/*** 每项的View的sub view Map*/private static SparseArray<View> mViewMap = new SparseArray<View>();/*** Content View*/static View mContentView;/*** 初始化ViewFinder, 实际上是获取到该页面的ContentView.* * @param context* @param layoutId*/public static void initContentView(Context context, int layoutId) {mInflater = LayoutInflater.from(context);mContentView = mInflater.inflate(layoutId, null, false);if (mInflater == null || mContentView == null) {throw new RuntimeException("ViewFinder init failed, mInflater == null || mContentView == null.");}}/*** @return*/public static View getContentView() {return mContentView;}/*** @param viewId* @return*/@SuppressWarnings("unchecked")public static <T extends View> T findViewById(int viewId) {// 先从view map中查找,假设有的缓存的话直接使用,否则再从mContentView中找View tagetView = mViewMap.get(viewId);if (tagetView == null) {tagetView = mContentView.findViewById(viewId);mViewMap.put(viewId, tagetView);}return tagetView == null ? null : (T) mContentView.findViewById(viewId);}
}

代码都在Github上了,请猛击这里。

Android中适用于ListView、GridView等组件的通用Adapter相关推荐

  1. Android中给listview/gridview设置动画(逐条加载条目动画)

    先看实现的效果如下: 演示效果如上:    上面的列表是GridView 要给这个GridView添加一个动画,才可以逐个加载.网上找了大量资料,不少人说用多线程加载,通过SetAdapter设置数据 ...

  2. 【错误记录】Android 中使用 Kotlin 为 EditText 组件设置文本报错 ( Type mismatch. Required:Editable. Found:String )

    文章目录 一.报错信息 二.解决方案 一.报错信息 在 Android 中使用 Kotlin 开发 , EditText 组件如下 : 布局文件 : <EditTextandroid:id=&q ...

  3. android列表滑到底部,Android中判断listview是否滑动到顶部和底部的实现方法

    今天实现listview的下拉刷新和上拉加载的时候,遇到了一个问题,*就是说需要根据listview中滑动的位置来进行下拉刷新和上拉加载.* 具体点,只有当我的listview滑动到最顶部的时候,这时 ...

  4. android 新闻功能列表,Android中通过ListView的实现简单新闻列表

    Android中通过ListView的实现简单新闻列表.本文分为两个部分,第一个部分是最基础的运用ListView实现列表展示.第二个部分是运用ListView实现新闻列表的展示. 这张图片是关于控件 ...

  5. android listview qq,Android中使用listview实现qq/微信好友列表

    首先附上运行结果: 如果你没有学过listview请你先看一看基本知识.不想再说的那么细了 太多了. 首先是listview布局 android:id="@+id/lv_view" ...

  6. android listview单击,如何在Android中处理ListView单击

    如何在Android中处理ListView单击 如何在ListView上收听点击事件? 这就是我现在拥有的 ListView list = (ListView)findViewById(R.id.Li ...

  7. Android中Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现)

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

  8. android中的 listview,Android中ListView的初步认识(一)

    ListView是安卓开发中常用的组件之一,它的作用是在一个垂直的列表中展现出所需的项目.接下来,我们看一下ListView的实现方法: 第一种 是常见的在XML中定义然后在activity中使用fi ...

  9. 一个适用于ListView/GridView/RecyclerView的通用适配器

    简化大量重复代码 支持多布局 自定义图片加载 常用数据操作 view复用 RecyclerView item 点击和长按事件 GitHub源码地址 简书地址 gradle依赖 dependencies ...

最新文章

  1. 8款效果精美的 jQuery 加载动画和进度条插件
  2. 32位有符号整数_[LeetCode] 8. 字符串转换整数 (atoi)
  3. python3 web框架_循序渐进Python3(十二) --0--  web之框架
  4. 【ES6(2015)】Reflect
  5. 简述RPL, DPL, CPL的区别与联系
  6. python13文件_python中13个实用的文件操作
  7. 2021/1/26-每日三题第33弹:皮皮虾,我们走 !你知道什么是面向对象编程和面向过程编程吗 ???
  8. 公众账号迁移:微信订阅号怎么升级服务号?
  9. idea+springmvc+spring+mybatis+maven整合返回json数据web api-
  10. linux 服务器内存清理内存缓存 详细说明 java jvm
  11. 这个开源项目绝绝子,一键生成好玩的矢量风格头像!
  12. Spark中repartition和coalesce的用法
  13. 百度AI 开放平台 语音合成
  14. 简报 | 井通公链实现商业应用真实用户数突破百万
  15. 上海航芯| BMS专题之BMS基础功能模块概述分享
  16. 如何不使用快压解压快压超高压缩比压缩的文件?
  17. Jacobi迭代法分量形式matlab,mtalab中jacobi迭代法
  18. Hyperledger Fabric 部署在多个主机上
  19. 微信支付V3 生成平台证书
  20. linux服务器免密登录

热门文章

  1. Tricentis的测试工具评测
  2. android中layout、drawable及styles的xml文件加载探索
  3. Java——去除字符串中的中文
  4. 自然数幂求和方法1:扰动法(求两次)
  5. Majority Element(169) Majority Element II(229)
  6. 【转载】C#中List集合使用Contains方法判断是否包含某个对象
  7. 各种快速幂(qaq)
  8. 1Python生成高质量Html文件:Pyh模块+Bootstrap框架
  9. Hystrix使用与分析
  10. spi 外设驱动(spi_driver)