构建一个ListView需要完成以下几点:
- 制作ListView中使用的layout文件,或者使用系统自带的。
- 往ListView中填充数据,主要通过Adapter实现。
- 实现用户点击的响应。
其中最主要也最灵活的部分是在第二步, 几个Adapter的使用方法,以及如何保持界面的流畅性都是比较难记住和难理解的部分。
几个常用的Adapter
Adapter | 含义 |
ArrayAdapter<T> | 支持泛型 |
SimpleAdapter | 用来绑定在xml中定义的控件对应的数据 常用ArrayList<HashMap<Object,Object>>去构建 |
SimpleCursorAdapter | 用来绑定游标得到的数据,如从SQLite取得的数据 |
BaseAdapter | 通用的基础适配器,灵活又难以掌握,注意优化的方法 |
构造ArrayAdapter:
- ArrayAdapter的构造函数又很多个版本,其中最常用的一种用法:
new ArrayAdapter<String>(Context context, int resource, String[] objects)
Parameters: <span style="white-space:pre"> </span>contex:The current context.<span style="white-space:pre"> </span>resource:The resource ID for a layout file containing a TextView to use when instantiating views.<span style="white-space:pre"> </span>objects The objects to represent in the ListView
- resource ID 可以使系统自定义的android.R.layout.simple_list_item_1, 也可以自己定义layout文件,但是一定要包含TextView。
- Objects 是要在resource里显示的内容,是一个String[]类型,这个要注意的。
public SimpleAdapter(Context context,List<? extends Map<String, ?>> data, int resource,String[] from, int[] to)
Parameters
context The context where the View associated with this SimpleAdapter is running data A List of Maps. Each entry in the List corresponds to one row in the list. The Maps contain the data for each row, and should include all the entries specified in "from" resource Resource identifier of a view layout that defines the views for this list item. The layout file should include at least those named views defined in "to" from A list of column names that will be added to the Map associated with each item. to The views that should display column in the "from" parameter. These should all be TextViews. The first N views in this list are given the values of the first N columns in the from parameter. - data使用ArrayList<HashMap<String,object>>, List中的每一个HashMap代表ListView中的每个item显示的内容。
- resource中式自己定义的layout文件。
- from是HashMap中每一列的key
- to 是layout中用来填充数据的每一列组件的ID
构造BaseAdapter- 上面介绍的三种Adapter都是BaseAdapter的子类,所以使用BaseAdapter是最灵活的当然也是最难以掌握的,它需要你实现一个继承它的子类并且实现一些抽象方法,实际上是实现Adatper这个类中的一些方法:
-
- public abstract int getCount()
How many items are in the data set represented by this Adapter.
- public abstract Object getItem (int position)
Get the data item associated with the specified position in the data set.
-
public abstract long getItemId(int position)
- 最后一个方法是最重要的方法,它是用来显示用户看到的view的内容,怎么样实现决定了这个listview显示的效率。
- listView的显示过程是通过getCount()获得需要显示的item总数,然后调用getView()向每个item里添加内容并显示,你可以直接在getView中向view赋值,但是这样的话,如果有很多Item要显示,而且你是一下子把所有的内容都塞到View里这样会造成界面滑动时的卡顿,甚至Out of Memory.
- 所以需要借助第二个参数convertView参数来保存要显示的内容到缓存里,使用的时候再取出。具体的实现可以看代码:
public View getView(final int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder = null; if(convertView == null){ holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.listview, null); holder.text1 = (TextView)convertView.findViewById(R.id.text1); holder.text2 = (TextView)convertView.findViewById(R.id.text2); holder.button = (Button)convertView.findViewById(R.id.button); convertView.setTag(holder); }else{ holder = (ViewHolder)convertView.getTag(); } holder.text1.setText(((HashMap<String, String>)getData().get(position)).get("text1")); holder.text2.setText(((HashMap<String, String>)getData().get(position)).get("text2")); holder.button.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub Log.d("press button", "position" + position); } }); return convertView; }
再使用ViewHolder来代替每次都调用findViewById来提高不少效率。Continue....