Android基础入门教程——2.4.7 构建一个可复用的自定义BaseAdapter
Android基础入门教程——2.4.7 构建一个可复用的自定义BaseAdapter
标签(空格分隔): Android基础入门教程
本节引言:
如题,本节给大家带来的是构建一个可复用的自定义BaseAdapter,我们每每涉及到ListView
GridView等其他的Adapter控件,都需要自己另外写一个BaseAdapter类,这样显得非常麻烦,
又比如,我们想在一个界面显示两个ListView的话,我们也是需要些两个BaseAdapter…
这,程序员都是喜欢偷懒的哈,这节我们就来写一个可复用的自定义BaseAdapter类~
1.我们一点点开始改:
首先我们把上节写的自定义BaseAdapter贴下,等下我们就要对他进行升级改造
/*** Created by Jay on 2015/9/21 0021.*/
public class MyAdapter extends BaseAdapter {private Context mContext;private LinkedList<Data> mData;public MyAdapter() {}public MyAdapter(LinkedList<Data> mData, Context mContext) {this.mData = mData;this.mContext = mContext;}@Overridepublic int getCount() {return mData.size();}@Overridepublic Object getItem(int position) {return mData.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null) {convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list, parent, false);holder = new ViewHolder();holder.img_icon = (ImageView) convertView.findViewById(R.id.img_icon);holder.txt_content = (TextView) convertView.findViewById(R.id.txt_content);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}holder.img_icon.setImageResource(mData.get(position).getImgId());holder.txt_content.setText(mData.get(position).getContent());return convertView;}//添加一个元素public void add(Data data) {if (mData == null) {mData = new LinkedList<>();}mData.add(data);notifyDataSetChanged();}//往特定位置,添加一个元素public void add(int position,Data data){if (mData == null) {mData = new LinkedList<>();}mData.add(position, data);notifyDataSetChanged();}public void remove(Data 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();}private class ViewHolder {ImageView img_icon;TextView txt_content;}}
升级1:将Entity设置成泛型
好的,毕竟我们传递过来的Entitiy实体类可能千奇百怪,比如有Person,Book,Wether等,所以我们
将Entity设置成泛型,修改后的代码如下:
public class MyAdapter<T> extends BaseAdapter {private Context mContext;private LinkedList<T> mData;public MyAdapter() {}public MyAdapter(LinkedList<T> mData, Context mContext) {this.mData = mData;this.mContext = mContext;}@Overridepublic int getCount() {return mData.size();}@Overridepublic Object getItem(int position) {return mData.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null) {convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list, parent, false);holder = new ViewHolder();holder.img_icon = (ImageView) convertView.findViewById(R.id.img_icon);holder.txt_content = (TextView) convertView.findViewById(R.id.txt_content);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}holder.img_icon.setImageResource(mData.get(position).getImgId());holder.txt_content.setText(mData.get(position).getContent());return convertView;}//添加一个元素public void add(T data) {if (mData == null) {mData = new LinkedList<>();}mData.add(data);notifyDataSetChanged();}//往特定位置,添加一个元素public void add(int position,T data){if (mData == null) {mData = new LinkedList<>();}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();}private class ViewHolder {ImageView img_icon;TextView txt_content;}}
好的,上面我们做的事仅仅是将Data类型换成了泛型T!
升级2:ViewHolder类的升级改造:
我们先来看看前面我们的ViewHolder干了什么?
答:findViewById,设置控件状态;
下面我们想在完成这个基础上,将getView()方法大部分的逻辑写到ViewHolder类里,
这个ViewHolder要做的事:
- 定义一个查找控件的方法,我们的思路是通过暴露公共的方法,调用方法时传递过来
控件id,以及设置的内容,比如TextView设置文本:
public ViewHolder setText(int id, CharSequence text){文本设置}
- 将convertView复用部分搬到这里,那就需要传递一个context对象了,我们把需要获取
的部分都写到构造方法中!
- 写一堆设置方法(public),比如设置文字大小颜色,图片背景等!
好的,接下来我们就来一步步改造我们的ViewHolder类
1)相关参数与构造方法:
public static class ViewHolder {private SparseArray<View> mViews; //存储ListView 的 item中的Viewprivate View item; //存放convertViewprivate 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;}ImageView img_icon;TextView txt_content;}
2)绑定ViewHolder与Item
在上面的基础上我们再添加一个绑定的方法
//绑定ViewHolder与itempublic 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;}
3)根据id获取集合中保存的控件
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;}
4) 接着我们再定义一堆暴露出来的方法
/*** 获取当前条目*/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;}//其他方法可自行扩展
好的,ViewHolder的改造升级完成~
升级3:定义一个抽象方法,完成ViewHolder与Data数据集的绑定
public abstract void bindView(ViewHolder holder, T obj);
我们创建新的BaseAdapter的时候,实现这个方法就好,另外,别忘了把我们自定义
的BaseAdapter改成abstact抽象的!
升级4:修改getView()部分的内容
@Overridepublic 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();}
2.升级完毕,我们写代码来体验下:
我们要实现的效果图:
就是上面有两个列表,布局不一样,但是我只使用一个BaseAdapter类来完成上述效果!
关键代码如下:
MainActivity.java:
public class MainActivity extends AppCompatActivity {private Context mContext;private ListView list_book;private ListView list_app;private MyAdapter<App> myAdapter1 = null;private MyAdapter<Book> myAdapter2 = null;private ArrayList<App> mData1 = null;private ArrayList<Book> mData2 = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mContext = MainActivity.this;init();}private void init() {list_book = (ListView) findViewById(R.id.list_book);list_app = (ListView) findViewById(R.id.list_app);//数据初始化mData1 = new ArrayList<App>();mData1.add(new App(R.mipmap.iv_icon_baidu,"百度"));mData1.add(new App(R.mipmap.iv_icon_douban,"豆瓣"));mData1.add(new App(R.mipmap.iv_icon_zhifubao,"支付宝"));mData2 = new ArrayList<Book>();mData2.add(new Book("《第一行代码Android》","郭霖"));mData2.add(new Book("《Android群英传》","徐宜生"));mData2.add(new Book("《Android开发艺术探索》","任玉刚"));//Adapter初始化myAdapter1 = new MyAdapter<App>(mData1,R.layout.item_one) {@Overridepublic void bindView(ViewHolder holder, App obj) {holder.setImageResource(R.id.img_icon,obj.getaIcon());holder.setText(R.id.txt_aname,obj.getaName());}};myAdapter2 = new MyAdapter<Book>(mData2,R.layout.item_two) {@Overridepublic void bindView(ViewHolder holder, Book obj) {holder.setText(R.id.txt_bname,obj.getbName());holder.setText(R.id.txt_bauthor,obj.getbAuthor());}};//ListView设置下Adapter:list_book.setAdapter(myAdapter2);list_app.setAdapter(myAdapter1);}}
我们写的可复用的BaseAdapter的使用就如上面所述~
3.代码示例下载:
ListViewDemo4.zip
贴下最后写好的MyAdapter类吧,可根据自己的需求进行扩展:
MyAdapter.java:
/*** Created by Jay on 2015/9/22 0022.*/
public abstract class MyAdapter<T> extends BaseAdapter {private ArrayList<T> mData;private int mLayoutRes; //布局idpublic MyAdapter() {}public MyAdapter(ArrayList<T> mData, int mLayoutRes) {this.mData = mData;this.mLayoutRes = mLayoutRes;}@Overridepublic int getCount() {return mData != null ? mData.size() : 0;}@Overridepublic T getItem(int position) {return mData.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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中的Viewprivate View item; //存放convertViewprivate 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与itempublic 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;}//其他方法可自行扩展}}
本节小结:
本节给大家介绍了如何来实现一个可供复用的BaseAdapter,当然大家可以在这个的基础上根据
自己的需求进行修改,比如通过异步设置网络图片等~改代码是参考鸿洋大神的视频写的:
视频链接:Android-打造万能适配器
另外,实际编写中遇到一些问题,非常感谢Berial(B神)的耐心点拨~
ありがとうございます~
Android基础入门教程——2.4.7 构建一个可复用的自定义BaseAdapter相关推荐
- Android入门教程四十之构建一个可复用的自定义BaseAdapter
如题,本节给大家带来的是构建一个可复用的自定义BaseAdapter,我们每每涉及到ListView GridView等其他的Adapter控件,都需要自己另外写一个BaseAdapter类,这样显得 ...
- 【Android 】零基础到飞升 | 构建一个可复用的自定义BaseAdapter
2.5.0 构建一个可复用的自定义BaseAdapter 本节引言: 如题,本节给大家带来的是构建一个可复用的自定义BaseAdapter,我们每每涉及到ListView GridView等其他的Ad ...
- 最新Android基础入门教程目录(完结版)
第一章:环境搭建与开发相关(已完结 10/10) https://blog.csdn.net/coder_pig/article/details/50000773 Android基础入门教程--1.1 ...
- 2015年最新Android基础入门教程目录(完结版)
2015年最新Android基础入门教程目录(完结版) 标签(空格分隔): Android基础入门教程 前言: 关于<2015年最新Android基础入门教程目录>终于在今天落下了帷幕,全 ...
- Android基础入门教程——1.5.1 Git使用教程之本地仓库的基本操作
Android基础入门教程--1.5.1 Git使用教程之本地仓库的基本操作 标签: Android基础入门教程 Git是什么? 一个分布式版本控制系统,和SVN类似,但远比SVN强大的一个版本控制系 ...
- Android基础入门教程——1.1 背景相关与系统架构分析
Android基础入门教程--1.1 背景相关与系统架构分析 标签: Android基础入门教程 1.Android背景与当前的状况 Android系统是由Andy Rubin创建的,后来被Googl ...
- android 编辑9图片,Android基础入门教程——1.6 .9(九妹)图片怎么玩
Android基础入门教程--1.6 .9(九妹)图片怎么玩 Android基础入门教程 1.本节引言: 可能有的一些疑问: 1.什么是.9图片? 答:图片后缀名前有.9的图片,如pic1.9.png ...
- android设置webview缓存目录,Android基础入门教程——7.5.5 WebView缓存问题
Android基础入门教程--7.5.5 WebView缓存问题 Android基础入门教程 本节引言:现在很多门户类信息网站,比如虎嗅,ifanr,钛媒体等等的APP,简单点说是信息阅读类的APP, ...
- Android基础入门教程——4.3.1 BroadcastReceiver牛刀小试
Android基础入门教程--4.3.1 BroadcastReceiver牛刀小试 标签(空格分隔): Android基础入门教程 本节引言 本节我们将来学习Android四大组件中的第三个:Bro ...
最新文章
- Winform分页控件之纯分页显示处理
- 0523-学习进度条
- python中memoryerror_解决python报错MemoryError
- Java 面向对象的程序设计(二)
- java cr_WildFly 10 CR 2发布– Java EE 7,Java 8,Hibernate 5,JavaScript支持热重载
- 两台虚拟服务器如何级联,[教程] 利用open vswitch建立vxlan隧道实现不同主机上的虚拟交换机级联...
- NLP数据增强方法总结:EDA、BT、MixMatch、UDA
- Android studio中的一次编译报错’Error:Execution failed for task ':app:transformClassesWithDexForDebug‘,困扰了两天
- python课程典范选优_python 实现选课系统
- 从Android运行时出发,打造我们的脱壳神器
- 计算机里保存文件时没有桌面,电脑在保存文件时桌面怎么不见了怎么办
- 人工智能专题讲学:开源数据支撑下的人物与装备分析
- 沐阳Git笔记02Git工作区与缓存区
- 论文笔记《Combining Events and Frames Using Recurrent Asynchronous Multimodal Networks for Monocular ...》
- centos系统安装教程
- 美国有超级计算机的学校,美国计算机排名 - 目前最牛的超级计算机前五名分别是?...
- 沙箱环境--虚拟环境
- 广州未成年子女落户政策需要什么申请条件和申办材料
- luts预设怎么导入ps中?
- 电信业重组进入倒计时 中国电信人士证实5-17重组 人事问题变数最大
热门文章
- linux 内核 input,初识linux中的input设备
- 南京邮电大学计算机网络ppt,南京邮电大学计算机网络第三章习题.ppt
- Cream的铁金库能否成为DeFi的流动性后盾?
- java 你的职业规划是什么,Java工程师的职业发展规划是什么
- 世界之窗3.0 起始页设置(转)
- 使用计算机打印汉字文档是汉字答案,天大2019年秋季考试《计算机应用基础》在线考核试题【满分答案】...
- 软件测试江湖(二)神兵利器篇
- 使用solarlunar库的阴阳历转换
- 互联网头条:寒冬,你们全家都寒冬
- 最好用的屏幕截图抓屏工具(FastStone Capture) 绿色版下载,首选推荐!