Android开发学习——ListView+BaseAdapter的使用
ListView
就是用来显示一行一行的条目的
MVC结构
* M:model模型层,要显示的数据 ————people集合
* V:view视图层,用户看到的界面 ————ListView
* c:control控制层,操作数据如何显示 ————adapter对象
每一个条目都是一个View对象
BaseAdapter
* 必须实现的两个方法
* 第一个
//系统调用此方法,用来获知模型层有多少条数据
@Override
public int getCount() {
return people.size();
}
* 第二个
//系统调用此方法,获取要显示至ListView的View对象
//position:是return的View对象所对应的数据在集合中的位置
@Override
public View getView(int position, View convertView, ViewGroup parent) {
System.out.println("getView方法调用" + position);
TextView tv = new TextView(MainActivity.this);
//拿到集合中的元素
Person p = people.get(position);
tv.setText(p.toString());
//把TextView的对象返回出去,它会变成ListView的条目
return tv;
}
屏幕上能显示多少个条目,getView方法就会被调用多少次,屏幕向下滑动时,getView会继续被调用,创建更多的View对象显示至屏幕
条目的缓存
当条目划出屏幕时,系统会把该条目缓存至内存,当该条目再次进入屏幕,系统在重新调用getView时会把缓存的条目作为convertView参数传入,但是传入的条目不一定是之前被缓存的该条目,即系统有可能在调用getView方法获取第一个条目时,传入任意一个条目的缓存
代码如下:
activity_main.xml:
<LinearLayout 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" tools:context="com.example.list.MainActivity" > <ListView
android:id="@+id/lv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
></ListView> </LinearLayout>
item.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="vertical" >
<ImageView
android:id="@+id/iv"
android:src="@drawable/xing"
android:layout_width="80dp"
android:layout_height="80dp" />
<TextView
android:id="@+id/t1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/t2"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> </LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
List<shopInfo> l;
ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
//准备集合数据
l = new ArrayList<shopInfo>();
l.add(new shopInfo(R.drawable.xing, "name-1", "content-1"));
l.add(new shopInfo(R.drawable.xing, "name-2", "content-2"));
l.add(new shopInfo(R.drawable.xing, "name-3", "content-3"));
l.add(new shopInfo(R.drawable.xing, "name-4", "content-4"));
l.add(new shopInfo(R.drawable.xing, "name-5", "content-5"));
l.add(new shopInfo(R.drawable.xing, "name-6", "content-6"));
l.add(new shopInfo(R.drawable.xing, "name-7", "content-7"));
l.add(new shopInfo(R.drawable.xing, "name-8", "content-8"));
//准备BaseAdapter对象
MyAdapter a = new MyAdapter();
//设置Adapter显示数据
lv.setAdapter(a); }
//这个类可以写在里面,也可以写在外面
public class MyAdapter extends BaseAdapter { @Override
public int getCount() {
// TODO Auto-generated method stub
return l.size();
} @Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
} @Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
} //第一种:没有任何处理,不建议这样写。如果数据量少看将就,但是如果列表项数据量很大的时候,会每次都重新创建View,设置资源,严重影响性能,所以从一开始就不要用这种方式
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
// 加载item的布局
View view = View.inflate(MainActivity.this, R.layout.item, null); shopInfo s = l.get(position);
ImageView i = (ImageView) view.findViewById(R.id.iv);
TextView t1 = (TextView) view.findViewById(R.id.t1);
TextView t2 = (TextView) view.findViewById(R.id.t2); i.setImageResource(s.getIcon());
t1.setText(s.getName());
t2.setText(s.getContent());
convertView = view ;
return convertView;
} }
}
shopInfo.java
//每行item的数据信息封装类
public class shopInfo {
private int icon;
private String name;
private String content; public int getIcon() {
return icon;
}
public void setIcon(int icon) {
this.icon = icon;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public shopInfo(int icon, String name, String content) {
super();
this.icon = icon;
this.name = name;
this.content = content;
}
@Override
public String toString() {
return "shopInfo [icon=" + icon + ", name=" + name + ", content="
+ content + "]";
}
public shopInfo() {
super();
// TODO Auto-generated constructor stub
} }
运行结果如下:
接下来实现getView()的方法和上边的实现一样的功能。
第二种ListView优化:通过缓存convertView,这种利用缓存contentView的方式可以判断如果缓存中不存在View才创建View,如果已经存在可以利用缓存中的View,提升了性能
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
{
convertView = mInflater.inflate(R.layout.list_item, null);
} ImageView img = (ImageView)convertView.findViewById(R.id.iv) ;
TextView title = (TextView)convertView.findViewById(R.id.t1);
TextView info = (TextView)ConvertView.findViewById(R.id.t2);
img.setImageResource(R.drawable.xing);
title.setText("Hello");
info.setText("world"); return convertView;
}
第三种ListView优化:通过convertView+ViewHolder来实现,ViewHolder就是一个静态类,使用 ViewHolder 的关键好处是缓存了显示数据的视图(View),加快了 UI 的响应速度。
当我们判断 convertView == null 的时候,如果为空,就会根据设计好的List的Item布局(XML),来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件(XML布局里面的那些控件)。再用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。(看下面代码中)
如果convertView不为空的时候,就会直接用convertView的getTag(),来获得一个ViewHolder。
public View getView(int position, View convertView, ViewGroup parent) {
// LayoutInflater mInflater = null;
ViewHolder holder = null;
shopInfo s = l.get(position);
if (convertView == null) {
holder = new ViewHolder();
// convertView = LinearLayout.inflate(MainActivity.this,
// R.layout.item, null);
convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, null);
/* 得到各个控件的对象 */
holder.iv = (ImageView) convertView.findViewById(R.id.iv);
holder.t1 = (TextView) convertView.findViewById(R.id.t1);
holder.t2 = (TextView) convertView.findViewById(R.id.t2); // to
// ItemButton convertView.setTag(holder); // 绑定ViewHolder对象
} else {
holder = (ViewHolder) convertView.getTag(); // 取出ViewHolder对象
} /* 设置TextView显示的内容,即我们存放在动态数组中的数据 */ holder.iv.setImageResource(s.getIcon());
holder.t1.setText(s.getName());
holder.t2.setText(s.getContent()); return convertView; } /* 存放控件 的ViewHolder */
public final class ViewHolder {
public ImageView iv;
public TextView t1;
public TextView t2;
}
在上述的代码中方法getView(int position, View convertView, ViewGroup parent)的方法体中,holder这个变量其实就是一个每一个item的View的结构。
这个holder结构存储了item对应布局里面的一些组件,而convertView.setTag(holder),就是把convertView中的Tag关联到holder这个结构中。
而convertView.getTag(),就是把convertView中的Tag取出来。
最后的holder.textView.setText(mData.get(position));就是把holder中的对应的组件初始化或者重定义(改变一些值),然后就可以显示出不同的内容了。
如果要实现单双行颜色交替
MainActivity.java:
加下边三个语句就可以了。
public class MainActivity extends Activity {
List<shopInfo> l;
ListView lv;
private int[] colors = new int[] { 0xff3cb371, 0xffa0a0a0 };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
// 准备集合数据
l = new ArrayList<shopInfo>();
l.add(new shopInfo(R.drawable.xing, "name-1", "content-1"));
l.add(new shopInfo(R.drawable.xing, "name-2", "content-2"));
l.add(new shopInfo(R.drawable.xing, "name-3", "content-3"));
l.add(new shopInfo(R.drawable.xing, "name-4", "content-4"));
l.add(new shopInfo(R.drawable.xing, "name-5", "content-5"));
l.add(new shopInfo(R.drawable.xing, "name-6", "content-6"));
l.add(new shopInfo(R.drawable.xing, "name-7", "content-7"));
l.add(new shopInfo(R.drawable.xing, "name-8", "content-8"));
// 准备BaseAdapter对象
MyAdapter a = new MyAdapter();
// 设置Adapter显示数据
lv.setAdapter(a); } // 这个类可以写在里面,也可以写在外面
public class MyAdapter extends BaseAdapter { @Override
public int getCount() {
// TODO Auto-generated method stub
return l.size();
} @Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
} @Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
// 加载item的布局
// View view = View.inflate(MainActivity.this, R.layout.item, null);
//
// shopInfo s = l.get(position);
// ImageView i = (ImageView) view.findViewById(R.id.iv);
// TextView t1 = (TextView) view.findViewById(R.id.t1);
// TextView t2 = (TextView) view.findViewById(R.id.t2);
//
// i.setImageResource(s.getIcon());
// t1.setText(s.getName());
// t2.setText(s.getContent());
// convertView = view ;
// return convertView; // LayoutInflater mInflater = null; // if(position%2==0){
// lv.setBackgroundColor(Color.argb(250 , 255 , 255 , 255 ));
// }else{
// lv.setBackgroundColor(Color.argb(250 , 224 , 243 , 250 ));
// } ViewHolder holder = null;
shopInfo s = l.get(position);
if (convertView == null) {
holder = new ViewHolder();
// convertView = LinearLayout.inflate(MainActivity.this,
// R.layout.item, null);
convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, null);
/* 得到各个控件的对象 */
holder.iv = (ImageView) convertView.findViewById(R.id.iv);
holder.t1 = (TextView) convertView.findViewById(R.id.t1);
holder.t2 = (TextView) convertView.findViewById(R.id.t2); // to
// ItemButton convertView.setTag(holder); // 绑定ViewHolder对象
} else {
holder = (ViewHolder) convertView.getTag(); // 取出ViewHolder对象
} /* 设置TextView显示的内容,即我们存放在动态数组中的数据 */ holder.iv.setImageResource(s.getIcon());
holder.t1.setText(s.getName());
holder.t2.setText(s.getContent()); int colorPos = position % colors.length;
convertView.setBackgroundColor(colors[colorPos]); return convertView; } /* 存放控件 的ViewHolder */
public final class ViewHolder {
public ImageView iv;
public TextView t1;
public TextView t2;
} }
}
效果如图:
Android开发学习——ListView+BaseAdapter的使用的更多相关文章
- Android UI学习 - ListView (android.R.layout.simple_list_item_1是个什么东西)
Android UI学习 - ListView -- :: 标签:Android UI 移动开发 ListView ListActivity 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始 ...
- Android开发学习之路-RecyclerView滑动删除和拖动排序
Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...
- Android开发学习路线的七个阶段和步骤
Android开发学习路线的七个阶段和步骤 Android学习参考路线 第一阶段:Java面向对象编程 1.Java基本数据类型与表达式,分支循环. 2.String和St ...
- Android开发学习路线图
Android开发学习方法: Android是一个比较庞大的体系,从底层的Linux内核到上层的应用层,各部分的内容跨度也比较大.因此,一个好的学习方法对我们学习Android开发很重要. 在此建议, ...
- android开发学习笔记000
使用书籍:<疯狂android讲义>——李刚著,2011年7月出版 虽然现在已2014,可我挑来跳去,还是以这本书开始我的android之旅吧. “疯狂源自梦想,技术成就辉煌.” 让我这个 ...
- Android开发学习总结(一)——搭建最新版本的Android开发环境
Android开发学习总结(一)——搭建最新版本的Android开发环境(转) 最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是 ...
- Android开发学习之LauncherActivity开发启动的列表
Android开发学习之LauncherActivity开发启动的列表 创建项目:OtherActivity 项目运行结果: 建立主Activity:OtherActivity.java [jav ...
- 最实用的Android开发学习路线分享
Android开发学习路线分享.Android发展主导移动互联发展进程,在热门行业来说,Android开发堪称火爆,但是,虽然Android有着自身种种优势,但对开发者的专业性要求也是极高,这种要求随 ...
- Android开发学习必备的java知识
Android开发学习必备的java知识本讲内容:对象.标识符.关键字.变量.常量.字面值.基本数据类型.整数.浮点数.布尔型.字符型.赋值.注释 Java作为一门语言,必然有他的语法规则.学习编程语 ...
随机推荐
- Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
http://www.xuebuyuan.com/558284.html 方法一 public class MainActivity extends Activity { @Override prot ...
- ASP.NET MVC Ajax.ActionLink 简单用法
ASP.NET MVC 项目中,如何使用类似于 iframe 的效果呢?或者说 Ajax 局部刷新,比如下面操作: 我们想要的效果是,点击 About 链接,页面不刷新(地址栏不变),然后下面的内容进 ...
- weight属性你用的真的6嘛?
相信大家在日常开发中一定使用过weight这个属性,它的作用一个是权重,另一个就是渲染优先级,但是你真的能很6的使用它嘛?如果不是,那么请继续往下看!!! 我们知道,当weight起到不同作用的时候, ...
- 利用private font改变PDF文件的字体
利用private font改变PDF文件的字体 前几天做项目,需要使用未安装的字体来改变PDF的文件.以前并没有实现过类似的功能,幸运的是我在网上找到了类似的教程,并成功实现了这个功能. 下面就跟大 ...
- JavaWeb:EL表达式
JavaWeb:EL表达式 说明 1.Expression Language语言,一种用于JSP文件中的数据访问的语言. 2.能够简化JSP文件中该数据访问的代码,可用来替代传统的基于<%= % ...
- Ajax.BeginForm VS Html.BeginForm
有的人说,AJAX一听,高大上,HTML一听,死老土,所以AJAX更好.其实这是错误的.每种方法有它不同的用途.现在做如下总结: @using (Ajax.BeginForm("Login& ...
- 12.Struts2自定义拦截器
12.自定义拦截器 拦截器是Struts2的一个重要特性.因为Struts2的大多数核心功能都是通过拦截器实现的. 拦截器之所以称之为“拦截器”,是因为它可以拦截Action方法的执行, ...
- T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll
生成实体就是这么简单,只要建一个T4文件和 文件夹里面放一个DLL. 使用T4模板教程 步骤1 创建T4模板 ,一定要自已新建,把T4代码复制进去,好多人因为用我现成的T4报错(原因不明) 点击添加文 ...
- RegQueryValueEx正确使用方法
项目中需要读取注册表中的HKEY_CLASSES_ROOT主键下一个子键的值,看了看MSDN的说明,有RegOpenKeyEx和RegQueryValueEx两个函数可以用.也没仔细阅读函数说明,就写 ...
- 使用CodeDom动态生成类型
.NET 3.5的时候加入了匿名类型这个特性,我们可以直接使用 new {name="abc"} 来直接生成一个对象.这个特性现在应用的地方很多,比如dapper的查询参数都是用匿 ...