====================================
手写了20页的word,在附件中
====================================
9 喜欢上Lists
ListView是android中最重要的一个部件,因为它使用的如此频繁。不论是从联系人中选择一个联系人,还是发一封邮件,还是读一个电子书。Listview都是最好用的
当然,如果它不仅仅展示文本的话,会更加有魅力,不是嘛?
好消息是,正如前面说的一样,我们可以定制各种列表选项样式,比如带有图片的,或者带有选择按钮的。等等。。
开始吧
我们知道list是由很多row(行)来构成的,那么我们不仅可以用一行文本来填充,也可以为行添加图标Icon.或者 checkbox等等。我们需要做的事情就是,为是适配器提供丰富的数据,然后帮助适配器用丰富的视图展现出来即可。
那么,我们通过下面的例子来看下
很简单,就是一行部件。左边是一个图片,右边是一个文本。
哪么我们是否可以把这个布局用在listview中去呢?
默认情况下,android是不知道你想让它用这种布局的。为了实现这种效果。你需要按照下面方式来做:
仔细看这个代码,这个代码修改了之前章节中的例子。但是,唯一的区别是
我们在设置适配器的时候,告诉android,我要是用自己的layout,而不是系统自己的
效果如下:
我们通过代码可以看到,我们需要引用 res/layout/下面的一个叫做Row的布局,这个布局就是你自己设置的,布局了,具体如何设置,我想不用说了吧,刚才那个layout就是我们创建好的R.layout.Row了。。
动态表现。
提供给自定义的可修改的布局,用于修饰每一行,这种技术在处理简单的情况的时候,是很方便的。但是,如果你想处理比较复杂的场景的时候,可能就会遇到下面的情况了:
l 不是每一行都会用一样的布局(有的时候一行文本,有的则是两行文本)
l 你需要配置部件给每一行(但是,实际运用的时候,每一行的图标不可能都一样对吧?)
这时候,最好的办法就是创建自己的适配器了~~~~~~重写getView()方法。并构造你自己的行就可以了。 getView()方法表示你要返回一个View,这个View会保存数据,并被放在ListView中
那么,让我们重新实现刚才那个例子。利用getView()
可以看到,我们设置setAdapter()的时候,传递的参数是我们自定义的适配器
重点看到getView()方法
介绍Inflation
在我们上面的情况,ViewInFlate的意思是,将一个xml的布局,转换为一个指定的view对象。我们就可以通过控制这个对象,来修改对象中的成员变量了~~而不是直接修改layout 这个xml文件。强大吧~~~我们不需要使用xml的各种解析器来做,只需要用ViewInFlate这个类就可以完成我们要将xml->object的工作哦。
在上面的例子中,我们转换了R.layout.row这个布局,
并得到了一个View对象。
其实,这个对象呢,就是一个LinearLayout对象,里面包含着一个ImageView和一个TextView。就像xml 文件中定义的一样了。
那么,既然我们得到了这个View。初始的时候,这个View是空的。因为这个static静态的布局文件,不知道自己的应该放什么数据在里面。我们的工作就是自定义里面的数据啦~~
先得到View中的部件,然后依次给他们填充数据,就ok了~~
简单不?
来看下最终的界面吧:
更好,更强大,更快速
我们上面所实现的getView()方法,不是高效率的。因为每一次我们滚动屏幕,都需要重新创建一个View对象来自适应数据显示。因为Android不会缓冲我们之前已经创建好的。如果返回上面的数据,又需要重新创建,这肯定不是很好的解决放啊啦~~
我们来看下几个小技巧吧~~
直接看代码:
我们需要仔细看下 getView()方法的参数,它有个参数叫做convertView, 它其实就是你之前访问的时候创建的Views。~如果第一次调用该方法,则是null,如果不是第一次调用,则会保存之前创建的Views。。所以它很关键哦~~
我们只需要在调用getView的时候,判断下数据是否已经存在,不存在的话就重新创建,否则就调用已经存在的~~
我们也可以使用持有者设计模式来做
我们在使用listveiw的时候,所作的很多事情就是调用findViewById()。然后把返回的数据保存在行里面。那么,我们关注的是每一行填充的内容(Content),所以我们可以考虑自己定义属于自己的Content。
所以,我们可以使用holder pattern(持有者模式)来进行设计。
下面我们定义一个类,叫做ViewWrapper
直接通过代码来看