最近学习到ListView控件,顺便做个笔记。
ListView我感觉是我刚刚学习Android比较繁杂的一个控件了。不过它的用途比较大,也比较实用的一个控件,所以重点关注一下。
ListView控件展示需要的东西就是适配器(Adapter),在我们以前学习的Java或者.net中也叫做适配器。listView中用到的适配器有三种分别为:ArrayAdapter、SimpleAdapter、SimpleCursorAdapter三种:
ArrayAdapter 最为简单,目前我只知道能展示简单文字
SimpleAdapter 有很好的扩展性,可以像ListView中添加控件之类的扩展
SimpleCursorAdapter 能够做简单的与数据库交流的操作。
接下来我将用几个示例来说明这三个适配器的用法。
ArrayAdapter:效果图如下
由于ListView展示的布局为系统默认的布局,所以我这里就没有布局文件的展示了。直接看代码:
package packages.listViewTest;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class ListViewTestActivity extends Activity {
/** Called when the activity is first created. */
private ListView listView;//定义一个空的ListView
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
listView = new ListView(this);
//此处就是ArrayAdapter实现的地方,通过setAdapter方法,
//ArrayAdapter构造函数的第一个参数为关联的Activity是哪个,
//第二个参数为系统默认的布局文件
//第三个参数为所要展示的数据
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_expandable_list_item_1, getData()));
setContentView(listView);
//设置listView控件的Item点击事件
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
if (arg2 == 0) {
//跳转ListViewSimpleCursor页面实现
Intent intent = new Intent();
intent.setClass(ListViewTestActivity.this,
ListViewSimpleCursor.class);
ListViewTestActivity.this.startActivity(intent);
} else if (arg2 == 1) {
//跳转ListViewSimple页面实现
Intent intent = new Intent();
intent.setClass(ListViewTestActivity.this,
ListViewSimple2.class);
ListViewTestActivity.this.startActivity(intent);
}
//吐丝控件使用
Toast.makeText(ListViewTestActivity.this,
arg0.getAdapter().getItem(arg2).toString(),
Toast.LENGTH_SHORT).show();
}
});
}
// 获取数据的方法
private List<String> getData() {
List<String> data = new ArrayList<String>();
data.add("SimpleCursorAdapter");
data.add("SimpleAdapter");
data.add("测试数据3");
data.add("测试数据4");
return data;
}
}
由于这个适配器可以和数据库做简单的交互,那么我们这里就做一个简单的示例,此示例用这个适配器来获取电话本中的信息来实现ListView效果图
首先我们在电话本中添加几个用户,如图:
接下来看一下我通过这个Adapter获取到的电话本中用户的姓名形成ListView的截图:
首先我们要在AndroidManifest.xml文件中加入这样一段代码<uses-permission android:name="android.permission.READ_CONTACTS" >,由于ListView这里我用的布局文件还是系统默认的,所以直接上代码:
package packages.listViewTest;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class ListViewSimpleCursor extends Activity {
private ListView listView;// 定义一个listView控件
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
listView = new ListView(this);
//获取电话本数据
Cursor cursor = getContentResolver().query(People.CONTENT_URI, null,
null, null, null);
startManagingCursor(cursor);
//SimpleCursorAdapter的第一个参数是要关联的Activity是哪个
//第二个参数是系统自带的样式,也可以通过自定义样式实现
//第三个参数是需要显示的数据内容
//第四个参数是包含数据库的列的String型数组,
//第五个参数包含布局文件中对应组件id的int型数组。其作用是自动的将String型数组所表示的每一列数据映射到布局文件对应id的组件上
//也就是将电话本中NAME列的数据显示在TextView空间上,这里还可以选择NUMBER电话号码等显示
ListAdapter listAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_expandable_list_item_1, cursor,
new String[] { People.NAME }, new int[] { android.R.id.text1 });
listView.setAdapter(listAdapter);
setContentView(listView);
}
}
SimpleAdapter
具有很好的扩展性,我们这里就做一个简单的示例让ListView中显示出图片,并实现相应自定义布局,效果如图所示:
首先看一下我的布局文件,我这里加了一个ImageView和两个TextView其中这两个TextView又放在了LinearLayout布局下做了相应的设置:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5px" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="22px" />
<TextView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="13px" />
</LinearLayout>
</LinearLayout>
接下来看我的代码实现:
package packages.listViewTest;
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 ListViewSimple2 extends Activity {
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
listView = new ListView(this);
// SimpleAdapter第一个参数所要帮顶的Activity
// 第二个参数所要展示的数据,数据中包含三列分别为title,info,img。
// 第三个参数所要显示的布局文件是哪一个,这里面是我们刚刚定义的那个simple的布局文件。
// 第四个参数是包含数据库的列的String型数组,由于我们的数据中包含title,info,img这三列,所以我们的String数组也要有这三列
// 第五个参数是一个int数组,所包含的数据就是我们要绑定数据的控件ID,这样就能将相应的数据帮顶到我们的控件上面了
SimpleAdapter adapter = new SimpleAdapter(this, GetData(),
R.layout.simple, new String[] { "title", "info", "img" },
new int[] { R.id.title, R.id.info, R.id.img });
listView.setAdapter(adapter);
setContentView(listView);
}
// 构造数据,以后可以通过读取数据库来实现
// 我们这里面通过ArrayList列表以及HashMap无非就是构造了一个数据表的形式。
public ArrayList<Map<String, Object>> GetData() {
ArrayList<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
HashMap<String, Object> map1 = new HashMap<String, Object>();
map1.put("title", "标题1");
map1.put("info", "骷髅头");
map1.put("img", R.drawable.img1);
HashMap<String, Object> map2 = new HashMap<String, Object>();
map2.put("title", "标题2");
map2.put("info", "稻草人");
map2.put("img", R.drawable.img2);
HashMap<String, Object> map3 = new HashMap<String, Object>();
map3.put("title", "标题3");
map3.put("info", "苹果");
map3.put("img", R.drawable.img3);
list.add(map1);
list.add(map2);
list.add(map3);
return list;
}
}
上面我们看到的形式大家估计都看出如何来做的,都是通过自定义一个ListView然后通过setContentView(listView)这样的方式实现的,大家应该都很清楚,setContentView(参数)以前大多数都是布局文件例如R.layout.main这样的类型的,而这里是将整个ListView放在了这个里面。那有没有另外一种方式实现呢?当然是有的android中有这样一个类ListActivity,它继承于Activity所以上面的SimpleAdapter这段代码又可以这样实现:
package packages.listViewTest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.SimpleAdapter;
//此处继承的是ListActivity这个类而不是Activity这个类了
//之前我们给ListView设置Adapter时都是用的setAdapter这个方法
//但是这里由于这个类继承自ListActivity这个类所以只需要设置setListAdapter这个方法即可
//其他和上面的示例无其他区别
public class ListViewSimple extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
SimpleAdapter adapter = new SimpleAdapter(this, GetData(),
R.layout.simple, new String[] { "title", "info", "img" },
new int[] { R.id.title, R.id.info, R.id.img });
setListAdapter(adapter);
}
// 构造数据,以后可以通过读取数据库来实现
public ArrayList<Map<String, Object>> GetData() {
ArrayList<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
HashMap<String, Object> map1 = new HashMap<String, Object>();
map1.put("title", "标题1");
map1.put("info", "骷髅头");
map1.put("img", R.drawable.img1);
HashMap<String, Object> map2 = new HashMap<String, Object>();
map2.put("title", "标题2");
map2.put("info", "稻草人");
map2.put("img", R.drawable.img2);
HashMap<String, Object> map3 = new HashMap<String, Object>();
map3.put("title", "标题3");
map3.put("info", "苹果");
map3.put("img", R.drawable.img3);
list.add(map1);
list.add(map2);
list.add(map3);
return list;
}
}
终于写完了我的ListView学习笔记,慢慢来,一点点我会把这门技术学到手的。哈哈。如果有朋友看见了,多给我提点建议,还有学习方法。内部的原理方面其实我懂的不多,也希望能够有很多朋友多多指点。