Android之listview万能适配器
2016-07-10 10:46
507 查看
什么叫万能适配器,其实就是这种适配器是万能的,所有需要使用适配器的组件,都可用这一个适配器就行。
既然这样,就来讲讲吧。
先来看看效果图:
当然了,这只是很简单的例子,很简单的布局,这里只是用来做个例子,以后也可以写别的布局,这个适配器都是适用的~
那我们就来讲讲怎么从普通的适配器到万能适配器的吧~
步骤:
1.首先普通的适配器的写法是--MyAdapter.class:
(1)首先我们得分析哪些代码是不变的,哪些是可变的,这样才能确定哪些代码能够减少。
这三个重写的方法应该是不变的。
只不过findViewById我们需要处理一下。所以我们应该把这些不变的代码抽取出来,不应该让用户重复写这些代码。
把这些代码抽取出来,当然这些代码都应该放在ViewHolder中
(2)新建一个类 ViewHolder.java
,View convertView, ViewGroup parent, int layoutId,这些参数都是加载布局文件所需要的。
然后就是这些代码需要抽取了:
然后在MyAdapter中getView方法代码如下:
这部分工作都完了,就只留下了为组件设置数据的那段代码了,这段代码由于是可变的,应该让用户来做,所以设置为抽象方法。
(3)新建一个类 CommonAdapter.java 继承BaseAdapter:
所以新建一个 Adapter 继承 CommonAdapter-MagicAdapter:
MainActivity:
既然这样,就来讲讲吧。
先来看看效果图:
当然了,这只是很简单的例子,很简单的布局,这里只是用来做个例子,以后也可以写别的布局,这个适配器都是适用的~
那我们就来讲讲怎么从普通的适配器到万能适配器的吧~
步骤:
1.首先普通的适配器的写法是--MyAdapter.class:
public class MyAdapter extends BaseAdapter{ private Context context; private List<Bean>datas; LayoutInflater layoutInflater; int resId;//布局文件 public MyAdapter(Context context, List<Bean> datas,int resId) { this.context = context; this.datas = datas; this.resId=resId; layoutInflater=LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return datas.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return datas.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub if(convertView==null){ convertView=layoutInflater.inflate(R.layout.listview,null); holder=new ViewHolder(); holder.title=(TextView) convertView.findViewById(R.id.title); holder.desc=(TextView) convertView.findViewById(R.id.desc); holder.time=(TextView) convertView.findViewById(R.id.time); holder.phone=(TextView) convertView.findViewById(R.id.phone); convertView.setTag(holder); }else{ holder=(ViewHolder) convertView.getTag(); } holder.title.setText(datas.get(position).getTitle()); holder.desc.setText(datas.get(position).getDesc()); holder.time.setText(datas.get(position).getTime()); holder.phone.setText(datas.get(position).getPhone()); } static class ViewHolder{ TextView title,time,desc,phone; } }2.万能适配器的编写步骤:
(1)首先我们得分析哪些代码是不变的,哪些是可变的,这样才能确定哪些代码能够减少。
这三个重写的方法应该是不变的。
@Override public int getCount() { // TODO Auto-generated method stub return datas.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return datas.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; }还有getView方法里面的一些代码:
if(convertView==null){ convertView=layoutInflater.inflate(R.layout.listview,null); holder=new ViewHolder(); holder.title=(TextView) convertView.findViewById(R.id.title); holder.desc=(TextView) convertView.findViewById(R.id.desc); holder.time=(TextView) convertView.findViewById(R.id.time); holder.phone=(TextView) convertView.findViewById(R.id.phone); convertView.setTag(holder); }else{ holder=(ViewHolder) convertView.getTag(); }
只不过findViewById我们需要处理一下。所以我们应该把这些不变的代码抽取出来,不应该让用户重复写这些代码。
把这些代码抽取出来,当然这些代码都应该放在ViewHolder中
(2)新建一个类 ViewHolder.java
public class ViewHolder { private View convertView,int mposition; //构造函数 //每个convertView会绑定一个ViewHolder对象 public ViewHolder(Context context, int mposition,View convertView,ViewGroup parent,int resId) { convertView=View.inflate(context, resId, null); this.convertView=convertView;this.mposition=mposition; convertView.setTag(this); } //拿到一个ViewHolder对象 public static ViewHolder get(Context context,int mposition, View convertView,ViewGroup parent,int resId){ if(convertView==null){ return new ViewHolder(context,mposition,convertView, parent, resId); }else { ViewHolder holder=(ViewHolder) convertView.getTag(); return holder; } } }传过来的参数包括:Context context, int mposition
,View convertView, ViewGroup parent, int layoutId,这些参数都是加载布局文件所需要的。
然后就是这些代码需要抽取了:
holder.title=(TextView) convertView.findViewById(R.id.title); holder.desc=(TextView) convertView.findViewById(R.id.desc); holder.time=(TextView) convertView.findViewById(R.id.time); holder.phone=(TextView) convertView.findViewById(R.id.phone);在类ViewHolder中新建方法:
//泛型,返回的是View的一个子类 //获取控件,通过控件的ID获取对应的控件,如果没有就加入mViews //resId是一个ID public <T extends View>T getView(int resId){ View view=mViews.get(resId); if(view==null){ //如果mViews没有相应的控件,我们就从convertView中找到这个控件, //并将这个控件和其ID存放在mViews view=convertView.findViewById(resId); mViews.put(resId, view); } return (T) view; }接下来要在ViewHolder这个类的返回convertView,这个返回值就容易了,直接返回就行了
//返回一个convertView对象 public View getmConvertView() { return convertView; }
然后在MyAdapter中getView方法代码如下:
@Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub //2. ViewHolder holder=ViewHolder.get(context, position, convertView, parent, resId); ((TextView)holder.getView(R.id.title)).setText(datas.get(position).getTitle()); ((TextView)holder.getView(R.id.desc)).setText(datas.get(position).getDesc()); ((TextView)holder.getView(R.id.time)).setText(datas.get(position).getTime()); ((TextView)holder.getView(R.id.phone)).setText(datas.get(position).getPhone()); return holder.getmConvertView(); }
这部分工作都完了,就只留下了为组件设置数据的那段代码了,这段代码由于是可变的,应该让用户来做,所以设置为抽象方法。
(3)新建一个类 CommonAdapter.java 继承BaseAdapter:
//(把MyAdapter中的getView方法抽取出来) public abstract class CommonAdapter<T> extends BaseAdapter{ private Context context; private List<T>data;//data是不明类型的数据 int resId;//布局文件 public CommonAdapter(Context context,List<T>data,int resId){ this.context=context; this.resId=resId; this.data=data; } @Override public int getCount() { // TODO Auto-generated method stub return data.size(); } //通过查看源代码发现,getItem方法不是在Baseadapter类中被调用的,而是在Adapterview中被调用的。 @Override public Object getItem(int position) { // TODO Auto-generated method stub return data.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder=ViewHolder.get(context, position, convertView, parent, resId); current(holder,getItem(position));//把那个getView方法抽取出来 return holder.getmConvertView(); } public abstract void current(ViewHolder holder,Object object); }然后有这些代码还不行~还要实现那个抽象方法~
所以新建一个 Adapter 继承 CommonAdapter-MagicAdapter:
public class MagicAdapter extends CommonAdapter<Bean>{ //resId是布局文件,调用基类的构造方法 public MagicAdapter(Context context, List<Bean> data, int resId) { super(context, data, resId); // TODO Auto-generated constructor stub } @Override public void current(ViewHolder holder, Object object) { // TODO Auto-generated method stub Bean bean=(Bean)object; ((TextView)holder.getView(R.id.title)).setText(bean.getTitle()); ((TextView)holder.getView(R.id.desc)).setText(bean.getDesc()); ((TextView)holder.getView(R.id.phone)).setText(bean.getPhone()); ((TextView)holder.getView(R.id.time)).setText(bean.getTime()); } }然后在MainActivity为listview加载适配器
listview.setAdapter(new MagicAdapter(MainActivity.this, datas,R.layout.listview));核心代码如下:
MainActivity:
public class MainActivity extends Activity { private ListView listview; private List<Bean>datas; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); initView(); } //初始化数据 public void initData() { // TODO Auto-generated method stub datas=new ArrayList<Bean>(); for(int i=1;i<10;i++){ Bean bean=new Bean("Android新技能"+i, "Android打造万能适配器", "2016-5-20", "10086"); datas.add(bean); } } //初始化控件 public void initView() { // TODO Auto-generated method stub listview=(ListView) findViewById(R.id.listview); //1. //listview.setAdapter(new MyAdapter(MainActivity.this, datas)); //2.调用这个适配器,把数据加载出来 listview.setAdapter(new MagicAdapter(MainActivity.this, datas,R.layout.listview)); } }Bean:
public class Bean { String title,desc,time,phone; public Bean(String title, String desc, String time, String phone) { super(); this.title = title; this.desc = desc; this.time = time; this.phone = phone; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }源码:下载
相关文章推荐
- 完美实现Android ListView中的TextView的跑马灯效果
- android上改变listView的选中颜色
- Delphi7中Listview的常用功能汇总
- Delphi控件ListView的属性及使用方法详解
- Android ListView弹性效果的实现方法
- android中ListView数据刷新时的同步方法
- Android提高之ListView实现自适应表格的方法
- Android中实现水平滑动(横向滑动)ListView示例
- Android ListView分页功能实现方法
- C#实现ListView选中项向上或向下移动的方法
- C#下listview如何插入图片
- Listview加载的性能优化是如何实现的
- C#实现listview Group收缩扩展的方法
- C# listview添加combobox到单元格的实现代码
- ListView 百分比进度条(delphi版)
- Android listview多视图嵌套多视图
- ListView Adapter优化 实例
- Android用ListView显示SDCard文件列表的小例子
- Adapter实现ListView带多选框等状态的自定义控件的注意事项
- asp.net ListView 数据绑定