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:
item.xml
MainActivity.java
public class MainActivity extends Activity { Listl; 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 (); 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 { Listl; 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 (); 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; } }}
效果如图: