android开发中实现个性化ListView的一些概念和思路
不管做什么技术,起码需要了解做的东西是什么。
感觉listview是android 的各种控件中比较复杂的一个。网上已经有一些教程来说明如何使用listView控件了,其实一开始我就觉得,我在我的程序中仅仅需要一个列表而已,为何在android中实现竟然要如此复杂?最近这些天的探索才发现,这种复杂其实是为了通用性和更高的可定制性而设计的。其实质是简化了逻辑,具有良好的分层设计,让思路变得清晰明了,确实是一种很高明的设计。
1. android中Activity 与View:
一个Activity 是一个android中看到的屏幕,或者说用户当前所操作的“活动”。但是这个“活动”并不能直接在屏幕上做什么事情,Activity只提供一些基础性的工作,比如监听系统事件、设置“View”、启动其他Activity等等。
View可以理解为一个“视图”,即Activity运行以后需要与给用户呈现的画面,Activity运行以后默认并不给用户提供显示的内容,而View提供视图呈现给用户。
2. ViewGroup:
ViewGroup 继承自View,但是ViewGroup是一中特殊的View,它功能是装载和管理一组下层的View和其让他ViewGroup,这样的好处是让View和其他ViewGroup形成一个树状的结构,而且可以为UI增加结构,将各种屏幕元素构成一个实体。
两个类都是在android.view 这个包里面的。所以使用时需引用各自的包。
Activity调用它的 SetContentView()方法的时候就可以指定一个View 对象,也可以指定一个ViewGroup对象,当Activity获得一个View对象的时候,同时也会把以这个View对象为根节点的树全部绘制出来。
android中的各种ui控件都是直接或间接继承自View类来实现的,做游戏开发时一般也是继承自View 来实现游戏的显示。
3.ListView:
ListView和View的关系是:
android.view.View | |||||
| android.view.ViewGroup | ||||
| android.widget.AdapterView<T extends android.widget.Adapter> | ||||
| android.widget.AbsListView | ||||
| android.widget.ListView |
可见ListView的本质是一组View的集合,即ViewGroup,一般使用的时候直接使用android提供的现成的ListView空间就足够了,不过使用使用ListView之前还需要一个适配器(Adapter)。
4. adapter 适配器:
我们认为ListView中的每一个item都有着相同布局和结构,我们没有必要重复编程为每一个item添加数据进去,这样不但可能降低程序的效率,还有可能增加程序的耦合度,把代码变得很复杂难懂,因此android采用了一种adapter 来把简单的数据映射到listview的每一个item里面。
v适配器类型,列表分为三种,ArrayAdapter,SimpleAdapter和SimpleCursorAdapter
其中以ArrayAdapter最为简单,只能展示一行字。SimpleAdapter有最好的扩充性,可以自定义出各种效果。SimpleCursorAdapter可以认为是SimpleAdapter对数据库的简单结合,可以方面的把数据库的内容以列表的形式展示出来。
5. 数据:
数据可以是String,可以是图像,也可以是其他Object。数据一般都是使用HashMap构成的List,list的每一节对应ListView的每一行。HashMap的每个键值数据映射到布局文件中对应id的组件上,如果没有现成的布局文件,那么就定义一个布局文件。 布局文件里面控件的id和HashMap的键值数据相对应。
如果需要动态更新ListView中某一行的数据,那么只需更新HashMap中的某一个节的数据即可。
一点想法:
当我们需要定制个性化的ListView的时候,android提供的ListView就显得有点局限了,因此需要我们自己继承ViewGroup来实现自己定制化的listView,比如sonyericsson 的android开发blog里面就提出一种全新的3d效果的listview,就是继承自AdapterView的。
要实现这种完全定制化的ListView呢,可能需要做下面这些工作:
1.继承自ViewGroup的自定义View。AdapterView 最适合。
2. 自定义布局文件 或者 重写onLayout()方法,在onLayout里面自定义item的布局。
3.继承Adapter,如果需要在绑定数据之前做一些处理,可以继承一个Adapter,在里面进行处理数据。
4.重写View的系统事件处理方法,比如要实现一些比较炫的效果,什么滑动、物理效果、弹性之类的,必然需要重写系统事件处理的方法,像onKeyUp()、onKeyDown()、onTouchEvent()这些。
5. 重写绘制方法,要实现前面那个3d ListView 势必需要重新绘制graphics ,所以还要取得graphics 下的canvas,这样来实现对图像的矩阵(matrix)变换、旋转等操作。
6. 在像素旋转和变换操作之后,画面可能出现严重的锯齿和走样,这时需要用到Paint 对象的反锯齿( anti-aliasing),或者更直接可靠的方法,读取绘制缓存然后直接绘制位图。
7. 3d变换中还需要将屏幕左边映射为空间中的3d坐标。用到camera等等。
当然方法还有其他的,很多,并不限于这些,我觉得广义上的的List还可以延伸到继承ViewGroup, 因为View的树状结构,我们是否可以定义出每一个item的结构、布局甚至完全不一样的‘List’出来呢。呵呵,我认为这是完全可以的。