Android开发之ListView
/*
* Android开发之ListView
*
* Created on: 2011-8-7
* Author: blueeagle
* Email: [email protected]
*/
最近在学习android开发过程中,发现有关ListView这个类的问题和处理方式的问题比较多。需要总结学习一下。
要学习ListView,不得不学习Adapter。在学习之前,先考察类的继承关系:
ListView:
java.lang.Object
android.view.View
android.view.ViewGroup
android.widget.AdapterView<T extends android.widget.Adapter>
android.widget.AbsListView
Adapter:
已知间接继承的子类
ArrayAdapter<T>, BaseAdapter, CursorAdapter, HeaderViewListAdapter,
ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter,
SpinnerAdapter, WrapperListAdapter
这里我也先不说我们在开发中经常会使用到什么类型的Adapter。先给几个应用程序截图来说明已经存在的ListView的应用,并对这些已经存在的ListView做实现DEMO。
单一的ListView
如图所示,这种ListView不存在任何复杂的内容,每行只显示一些文字。如果没有特殊要求的话,这是最简单最实用的一种ListView。
实现这种ListView有两种方式:
第一种是:不借助XML文件来直接实现:
源码如下:
[java] view plain copy print ?
-
-
-
-
-
-
-
-
- package com.blueeagle;
-
-
-
- import java.util.ArrayList;
-
- import android.app.Activity;
-
- import android.os.Bundle;
-
- import android.widget.ArrayAdapter;
-
- import android.widget.ListView;
-
-
-
- public class ListViewExActivity extends Activity {
-
- private ListView listView;
-
- @Override
-
- public void onCreate(Bundle savedInstanceState){
-
- super.onCreate(savedInstanceState);
-
-
-
- listView = new ListView(this);
-
- listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,getData()));
-
- setContentView(listView);
-
- }
-
-
-
- private ArrayList<String> getData(){
-
- ArrayList<String> myData = new ArrayList<String>();
-
- myData.add("思想决定行为 ");
-
- myData.add("行为形成习惯");
-
- myData.add("习惯决定性格");
-
- myData.add("性格决定命运");
-
-
-
- return myData;
-
- }
-
- }
/* * Android开发之ListView * ListViewExActivity.java * Created on: 2011-8-7 * Author: blueeagle * Email:
[email protected] */ package com.blueeagle; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; public class ListViewExActivity extends Activity { private ListView listView; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); listView = new ListView(this); listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,getData())); setContentView(listView); } private ArrayList<String> getData(){ ArrayList<String> myData = new ArrayList<String>(); myData.add("思想决定行为 "); myData.add("行为形成习惯"); myData.add("习惯决定性格"); myData.add("性格决定命运"); return myData; } }
第二种方法是借助XML文件:
源码如下:
[java] view plain copy print ?
-
-
-
-
-
-
-
-
- package com.blueeagle;
-
-
-
- import java.util.ArrayList;
-
- import android.app.Activity;
-
- import android.os.Bundle;
-
- import android.widget.ArrayAdapter;
-
- import android.widget.ListView;
-
-
-
- public class ListViewExActivity extends Activity {
-
- private ListView listView;
-
- @Override
-
- public void onCreate(Bundle savedInstanceState){
-
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.myListView);
-
- listView = (ListView)findViewById(R.id.myListView);
-
- listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,getData()));
-
- }
-
-
-
- private ArrayList<String> getData(){
-
- ArrayList<String> myData = new ArrayList<String>();
-
- myData.add("思想决定行为 ");
-
- myData.add("行为形成习惯");
-
- myData.add("习惯决定性格");
-
- myData.add("性格决定命运");
-
-
-
- return myData;
-
- }
-
- }
/* * Android开发之ListView * ListViewExActivity.java * Created on: 2011-8-7 * Author: blueeagle * Email:
[email protected] */ package com.blueeagle; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; public class ListViewExActivity extends Activity { private ListView listView; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.myListView); listView = (ListView)findViewById(R.id.myListView); listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,getData())); } private ArrayList<String> getData(){ ArrayList<String> myData = new ArrayList<String>(); myData.add("思想决定行为 "); myData.add("行为形成习惯"); myData.add("习惯决定性格"); myData.add("性格决定命运"); return myData; } }
myListView.xml
[html] view plain copy print ?
- <?xml version="1.0" encoding="utf-8"?>
-
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
- android:orientation="vertical"
-
- android:layout_width="fill_parent"
-
- android:layout_height="fill_parent"
-
- >
-
- <ListView
-
- android:id="@+id/myListView"
-
- android:layout_width="fill_parent"
-
- android:layout_height="wrap_content"
-
- />
-
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ListView android:id="@+id/myListView" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
说明:有时候我们在开发过程中,需要在一个没有xml的View中添加一个ListView控件,有时候我们可能需要在有xml文件描述的时候添加一个ListView控件。需要注意的是:setContentView()这个函数的先后顺序要写清楚。
在这种方法中我们使用了ArrayAdapter。
稍复杂点的ListView——添加了标题(描述)元素
如图所示,这种ListView只是比单一的ListView多了一个标题,或者说是描述的ListView,这种ListView应该是我们在实际开发中用的最多的一种ListView了。
同样的,实现这种ListView有两种方式。理论跟上面的一样,现在就举一种例子。
源码如下:
[java] view plain copy print ?
-
-
-
-
-
-
-
-
- package com.blueeagle;
-
-
-
- import java.util.ArrayList;
-
- import java.util.HashMap;
-
- import java.util.Map;
-
- import android.app.Activity;
-
- import android.os.Bundle;
-
- import android.widget.ListView;
-
- import android.widget.SimpleAdapter;
-
-
-
- public class ListViewExTitleActivity extends Activity {
-
- private String[] myTitle = { "思想决定行为", "行为形成习惯", "习惯决定性格", "性格决定命运","狂热的Android开发者"};
-
- private String[] myDescript = { "说话办事儿,首先要有一个好的思想,有了好思想,才能体现在行动上", "能够坚持的行动将成为习惯", "对事对人的习惯性行为表现为人的性格", "往往成就大事的人,都有着很好的性格",
-
- "狂热的Android程序员需要有一个好性格" };
-
- private String[] myNote = { "备注1", "备注2", "备注3", "备注4","备注5" };
-
- private ListView myListView;
-
-
-
- ArrayList<Map<String,Object>> mData= new ArrayList<Map<String,Object>>();;
-
- @Override
-
- public void onCreate(Bundle savedInstanceState) {
-
- super.onCreate(savedInstanceState);
-
- int lengh = myTitle.length;
-
- for(int i =0; i < lengh; i++) {
-
- Map<String,Object> item = new HashMap<String,Object>();
-
- item.put("title", myTitle[i]);
-
- item.put("Descript", myDescript[i]);
-
- item.put("note", myNote[i]);
-
- mData.add(item);
-
- }
-
- myListView = new ListView(this);
-
- SimpleAdapter adapter = new SimpleAdapter(this,mData,R.layout.layout_item_1,
-
- new String[]{"title","Descript","note"},new int[]{R.id.title,R.id.descript,R.id.note});
-
- myListView.setAdapter(adapter);
-
- setContentView(myListView);
-
- }
-
- }
/* * Android开发之ListView * ListViewExTitleActivity.java * Created on: 2011-8-7 * Author: blueeagle * Email:
[email protected] */ package com.blueeagle; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; import android.widget.SimpleAdapter; public class ListViewExTitleActivity extends Activity { private String[] myTitle = { "思想决定行为", "行为形成习惯", "习惯决定性格", "性格决定命运","狂热的Android开发者"}; private String[] myDescript = { "说话办事儿,首先要有一个好的思想,有了好思想,才能体现在行动上", "能够坚持的行动将成为习惯", "对事对人的习惯性行为表现为人的性格", "往往成就大事的人,都有着很好的性格", "狂热的Android程序员需要有一个好性格" }; private String[] myNote = { "备注1", "备注2", "备注3", "备注4","备注5" }; private ListView myListView; ArrayList<Map<String,Object>> mData= new ArrayList<Map<String,Object>>();; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); int lengh = myTitle.length; for(int i =0; i < lengh; i++) { Map<String,Object> item = new HashMap<String,Object>(); item.put("title", myTitle[i]); item.put("Descript", myDescript[i]); item.put("note", myNote[i]); mData.add(item); } myListView = new ListView(this); SimpleAdapter adapter = new SimpleAdapter(this,mData,R.layout.layout_item_1, new String[]{"title","Descript","note"},new int[]{R.id.title,R.id.descript,R.id.note}); myListView.setAdapter(adapter); setContentView(myListView); } }
layout_item_1.xml
[html] view plain copy print ?
- <?xml version="1.0" encoding="utf-8"?>
-
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
- android:orientation="vertical"
-
- android:layout_width="fill_parent"
-
- android:layout_height="fill_parent">
-
- <TextView
-
- android:id="@+id/title"
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content"
-
- android:textColor="#00ffff"
-
- android:textSize="22px" />
-
- <TextView
-
- android:id="@+id/descript"
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content"
-
- android:textColor="#FFFFFFFF"
-
- android:textSize="13px" />
-
- <TextView
-
- android:id="@+id/note"
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content"
-
- android:textColor="#FF0000"
-
- android:textSize="13px"
-
- android:layout_gravity="right"
-
- />
-
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#00ffff" android:textSize="22px" /> <TextView android:id="@+id/descript" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFFFF" android:textSize="13px" /> <TextView android:id="@+id/note" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FF0000" android:textSize="13px" android:layout_gravity="right" /> </LinearLayout>
说明:在这个例子里面我们使用到了SimpleAdapter。看这个名字,简单的Adapter,其实不是那么简单。查看手册,可以知道其构造函数以及意义:
public SimpleAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
第一个context :SimpleAdapter所要运行关联到的视图。一般而言,就是这个SimpleAdapter所在的Activity,所以这个参数一般是this。
第二个是一个泛型只要是一个List就行,这一般会想到是ArrayList,而他内部存储的则是Map或者继承自Map的对象,比如HashMap。每一个ArrayList中的一行就代表着呈现出来的一行,Map的键就是这一行的列名,值也是有列名的。
第三个资源文件,就是说要加载这个两列所需要的视图资源文件,也就是布局文件,可以定义成.xml的文件。
第四个参数是一个数组,主要是将Map对象中的名称映射到列名,一一对应
第五个是将第四个参数的值一一对象的显示(一一对应)在接下来的int形的id数组中,这个id数组就是LayOut的xml文件中命名id形成的唯一的int型标识符
在程序中:
[java] view plain copy print ?
- Map<String,Object> item = new HashMap<String,Object>();
-
- item.put("title", myTitle[i]);
-
- item.put("Descript", myDescript[i]);
-
- item.put("note", myNote[i]);
-
- mData.add(item);
Map<String,Object> item = new HashMap<String,Object>(); item.put("title", myTitle[i]); item.put("Descript", myDescript[i]); item.put("note", myNote[i]); mData.add(item);
这段代码里,一个item设置了三个值,也可以设置更少或者是更多的值。如果设置了更少或者更多的值,相应的需要在.xml文件里修改布局,同时修改程序里SimpleAdapter的第四个和第五个参数。即修改程序中:
[java] view plain copy print ?
- SimpleAdapter(this,mData,R.layout.layout_item_1,
-
- new String[]{"title","Descript","note"},new int[]{R.id.title,R.id.descript,R.id.note});
SimpleAdapter(this,mData,R.layout.layout_item_1, new String[]{"title","Descript","note"},new int[]{R.id.title,R.id.descript,R.id.note});
这段代码的参数,可以增加也可以减少。
特别要注意的是,在item里设置的值,还可以是图形或者是别的视图类型,如下实例。
ListView——添加了标题(描述)元素以及图片元素
如图所示,这种ListView只是比前面的ListView多了一个图标。这正是在上一个例子后面所说明的一样。只是添加了几行源码,如下:
ListViewExTitleActivity.java
添加了:
[java] view plain copy print ?
- item.put("image", R.drawable.icon);
-
- SimpleAdapter adapter = new SimpleAdapter(this,mData,R.layout.layout_item_1,
-
- new String[]{"image","title","Descript","note"},new int[]{R.id.imageicon,R.id.title,R.id.descript,R.id.note});
item.put("image", R.drawable.icon); SimpleAdapter adapter = new SimpleAdapter(this,mData,R.layout.layout_item_1, new String[]{"image","title","Descript","note"},new int[]{R.id.imageicon,R.id.title,R.id.descript,R.id.note});
layout_item_1.xml
添加了:
[html] view plain copy print ?
- <ImageView
-
- android:id="@+id/imageicon"
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content"
-
- />
<ImageView android:id="@+id/imageicon" android:layout_width="wrap_content" android:layout_height="wrap_content" />
这里需要注意的是:如果不喜欢每一个item的布局,可以修改xml布局文件里的结构,调整图片位置,字体位置等。
ListView——自定义特别的ListView
如图所示,我们在程序开发过程中,经常会遇见各种特定样式,类型等等的需求,在图中这种情况下,上述几种例子都不能很好的解决,这个时候就要自己定义了。自定义ListView是一个很有意思的过程。
ListView在绘制前会调用getCount()方法得到绘制次数,这个次数,实际上就是ListView的Item项数 ,然后实例化自己定义的一个Adapter,一般常用的有两种Adapter,一种是BaseAdapter,适合较少的List Item;另一种是BaseAdapter的子类:ArrayAdapter,适合较多,较复杂的List Item。这些Adapter都通过getView()方法一项一项的绘制ListView,所以我们可以在这里面根据position(当前绘制的ID)来任意的修改绘制的内容。
在举例之前,不得不说一下这个特别重要的函数getView():
查看手册可以得到getView的解释:
public abstract View getView (int position, View convertView, ViewGroup parent)
获取用于显示数据集中指定位置上的数据的视图。你可以手工创建一个视图, 也可以从 XML 布局文件中展开视图。展开视图时,父视图(GridView、ListView 等) 将应用默认的布局参数,除非你使用inflate(int, android.view.ViewGroup, boolean) inflate(int, android.view.ViewGroup, boolean)指定根视图,并指定附加到根元素。
参数
position |
要从适配器中取得的视图的位置. |
convertView |
要重用的旧视图,如果可能。注意,在使用之前你应该检查该视图是否非空, 并且是适当的类型。如果不能转化该视图来正确显示数据,该方法将创建新视图。 |
parent |
该视图最终关联到的父视图。 |
返回值
指定位置的数据对应的视图。
看的晕,不要紧,从例子入手:
首先我们来写java文件。我们写一个自己的adapter继承于BaseAdapter
[java] view plain copy print ?
-
-
-
-
-
-
-
-
- package com.blueeagle;
-
-
-
- import android.app.Activity;
-
- import android.content.Context;
-
- import android.graphics.Color;
-
- import android.os.Bundle;
-
- import android.view.LayoutInflater;
-
- import android.view.View;
-
- import android.view.ViewGroup;
-
- import android.widget.AdapterView;
-
- import android.widget.BaseAdapter;
-
- import android.widget.ImageView;
-
- import android.widget.ListView;
-
- import android.widget.TextView;
-
- import android.widget.Toast;
-
-
-
- public class ListViewExTitleActivity extends Activity {
-
- private String[] myTitle = { "思想决定行为", "行为形成习惯", "习惯决定性格", "性格决定命运","狂热的Android开发者","狂热的Android开发者"};
-
- private String[] myDescript = { "说话办事儿,首先要有一个好的思想,有了好思想,才能体现在行动上", "能够坚持的行动将成为习惯", "对事对人的习惯性行为表现为人的性格", "往往成就大事的人,都有着很好的性格",
-
- "狂热的Android程序员需要有一个好性格" ,"狂热的Android开发者"};
-
- private String[] myNote = { "备注1", "备注2", "备注3", "备注4","备注5" ,"狂热的Android开发者"};
-
- ListView myListView = null;
-
- NewTypeAdapter myAdapter = null;
-
- @Override
-
- public void onCreate(Bundle savedInstanceState) {
-
- super.onCreate(savedInstanceState);
-
- myListView = new ListView(this);
-
- myAdapter = new NewTypeAdapter(this);
-
- myListView.setAdapter(myAdapter);
-
- myListView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
-
- @Override
-
- public void onItemClick(AdapterView<?> arg0,View arg1,int arg2,long arg3){
-
- arg1.setBackgroundColor(Color.BLACK);
-
- System.out.println(arg2);
-
- Toast.makeText(ListViewExTitleActivity.this,"您选择了" + myTitle[arg2], Toast.LENGTH_LONG).show();
-
- }
-
- });
-
- setContentView(myListView);
-
- }
-
- class NewTypeAdapter extends BaseAdapter {
-
- private Context mContext;
-
- private int[] colors = new int[]{Color.RED,Color.BLUE,Color.GREEN,Color.WHITE};
-
- public NewTypeAdapter(Context context) {
-
- mContext = context;
-
- }
-
- @Override
-
- public int getCount() {
-
-
-
- return myTitle.length;
-
- }
-
- @Override
-
- public Object getItem(int position) {
-
-
-
- return position;
-
- }
-
- @Override
-
- public long getItemId(int position) {
-
-
-
- return position;
-
- }
-
- @Override
-
- public View getView(int position, View convertView, ViewGroup parent) {
-
-
-
- System.out.println(position);
-
- ImageView myIamge = null;
-
- TextView myTextTitle = null;
-
- TextView myTextDescript = null;
-
- TextView myTextNote = null;
-
-
-
- convertView = LayoutInflater.from(mContext).inflate(R.layout.layout_item_1, null);
-
- myIamge = (ImageView) convertView.findViewById(R.id.imageicon);
-
- myTextTitle =(TextView) convertView.findViewById(R.id.title);
-
- myTextDescript= (TextView) convertView.findViewById(R.id.descript);
-
- myTextNote= (TextView) convertView.findViewById(R.id.note);
-
-
-
-
-
- try{
-
- int j = position%colors.length;
-
- convertView.setBackgroundColor(colors[j]);
-
- myTextTitle.setText(myTitle[position]);
-
- myTextDescript.setText(myDescript[position]);
-
- myTextNote.setText(myNote[position]);
-
- myIamge.setImageResource(R.drawable.icon);
-
- }
-
- catch(Exception e){
-
- e.printStackTrace();
-
- }
-
- return convertView;
-
- }
-
- }
-
- }
/* * Android开发之ListView * ListViewExTitleActivity.java * Created on: 2011-8-7 * Author: blueeagle * Email:
[email protected] */ package com.blueeagle; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; public class ListViewExTitleActivity extends Activity { private String[] myTitle = { "思想决定行为", "行为形成习惯", "习惯决定性格", "性格决定命运","狂热的Android开发者","狂热的Android开发者"}; private String[] myDescript = { "说话办事儿,首先要有一个好的思想,有了好思想,才能体现在行动上", "能够坚持的行动将成为习惯", "对事对人的习惯性行为表现为人的性格", "往往成就大事的人,都有着很好的性格", "狂热的Android程序员需要有一个好性格" ,"狂热的Android开发者"}; private String[] myNote = { "备注1", "备注2", "备注3", "备注4","备注5" ,"狂热的Android开发者"}; ListView myListView = null; NewTypeAdapter myAdapter = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); myListView = new ListView(this); myAdapter = new NewTypeAdapter(this); myListView.setAdapter(myAdapter); myListView.setOnItemClickListener(new AdapterView.OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0,View arg1,int arg2,long arg3){ arg1.setBackgroundColor(Color.BLACK); System.out.println(arg2); Toast.makeText(ListViewExTitleActivity.this,"您选择了" + myTitle[arg2], Toast.LENGTH_LONG).show(); } }); setContentView(myListView); } class NewTypeAdapter extends BaseAdapter { private Context mContext; private int[] colors = new int[]{Color.RED,Color.BLUE,Color.GREEN,Color.WHITE}; public NewTypeAdapter(Context context) { mContext = context; } @Override public int getCount() { // TODO Auto-generated method stub return myTitle.length; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return position; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub System.out.println(position); ImageView myIamge = null; TextView myTextTitle = null; TextView myTextDescript = null; TextView myTextNote = null; //if (convertView == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.layout_item_1, null); myIamge = (ImageView) convertView.findViewById(R.id.imageicon); myTextTitle =(TextView) convertView.findViewById(R.id.title); myTextDescript= (TextView) convertView.findViewById(R.id.descript); myTextNote= (TextView) convertView.findViewById(R.id.note); // } // else try{ int j = position%colors.length; convertView.setBackgroundColor(colors[j]); myTextTitle.setText(myTitle[position]); myTextDescript.setText(myDescript[position]); myTextNote.setText(myNote[position]); myIamge.setImageResource(R.drawable.icon); } catch(Exception e){ e.printStackTrace(); } return convertView; } } }
layout_item_1.xml:
[html] view plain copy print ?
- <?xml version="1.0" encoding="utf-8"?>
-
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
-
-
- android:orientation="vertical"
-
- android:layout_width="fill_parent"
-
- android:layout_height="fill_parent">
-
- <ImageView
-
- android:id="@+id/imageicon"
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content"
-
- />
-
- <TextView
-
- android:id="@+id/title"
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content"
-
- android:textColor="#00ffff"
-
- android:textSize="22px" />
-
-
-
- <TextView
-
- android:id="@+id/descript"
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content"
-
- android:textColor="#FFFFFFFF"
-
- android:textSize="13px" />
-
-
-
- <TextView
-
- android:id="@+id/note"
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content"
-
- android:textColor="#FF0000"
-
- android:textSize="13px"
-
- />
-
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/imageicon" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#00ffff" android:textSize="22px" /> <TextView android:id="@+id/descript" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFFFF" android:textSize="13px" /> <TextView android:id="@+id/note" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FF0000" android:textSize="13px" /> </LinearLayout>
说明:首先说明的是,这个例子自定义了类:NewTpyeAdapter,继承BaseAdapter,当然要实现BaseAdapter的各个成员方法。程序OnCreate方法中主要有四个内容:实例化NewTypeAdapter,实例化ListView,然后利用myListView.setAdapter(myAdapter);将ListView和NewTypeAdapter绑定。
这里需要特别注意的是:如果ListViewExTitleActivity继承的是Activity,则必须要加上setContentView(myListView)这句,如果继承的是ListActivity,则不用加啦,因为其本身就是一个List了。
接下来就是我们的最重要的方法,getView()方法。
在说getView方法之前说几个可能出现的问题:
1. getView()方法不会被调用;
2. 当ListView在一个屏幕内显示不全的时候,拖动后的数据会重复。
3. 如果在ListView中的某个Item中加入一个按钮的话,这个Item的点击事件将消失。
下面来解答这些问题:getView()这个方法的调用是有条件的。我在开始试验的时候,getView()方法一直不会被调用,后来才发现,如果getCount ()的返回值为0的话,则不会被调用。因此需要把BaseAdapter的成员方法都写全。
对于重复问题:如上面源码,如果加入了if(convertView ==null)则表示其一屏幕显示了从数据空间读取的内容,滚动后则不会再从数据空间读取,而是从现有空间读取。手册中说使用的时候先判断是否为空,但是我这里去掉了这个if语句,则能够实现效果,但是可能带来效率问题,这样的话每次回滚,则每次会重绘。
对于加入按钮点击事件消失的问题,是因为按钮的焦点抢夺了listview项的焦点。因此listview的项就点击不到了。
总结:
以上说了四种ListView的实现方式。当然第四种还可以引申开去。比如我们可以继承ArrayAdapter;也可以在每个ListItem中加入一个按钮,加入按钮只需要添加该按钮的消息响应函数就可以了。
相信经过上面的学习,对ListView这个类应该有一定的掌握了,一些大大小小的问题应该都能够解决了。