如題,本文將介紹 listview的點擊事件,simpleAdapter和arrayadapter的原理和使用.
1.ListView的注冊點擊事件
復制代碼
//注冊點擊事件
personListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
/**
*
* @param parent 當前ListView
* @param view 代表當前被點擊的條目
* @param position 當前條目的位置
* @param id 當前被點擊的條目的id
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(tag,"點擊了!");
/*
方法 1:
*/
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
Toast.makeText(MyActivity.this,"姓名是1:"+tv_name.getText(),Toast.LENGTH_SHORT).show();
/*
方法 2:
*/
String name = persons.get(position).getName();
Toast.makeText(MyActivity.this,"姓名是2:"+name,Toast.LENGTH_SHORT).show();
/*
方法 3:
*/
Person p=(Person)parent.getItemAtPosition(position);
Toast.makeText(MyActivity.this,"姓名是3:"+p.getName(),Toast.LENGTH_SHORT).show();
}
});
復制代碼
注:注冊一個onItemClick事件,方法1:利用當前被點擊條目的視圖根據id找到tv_name,然後使用吐司顯示被點擊的內容.
方法2:利用當前被點擊條目的位置,然後根據位置取到姓名;
方法3:parent在這裡表示ListView的位置,這裡得到被點擊條目的位置,取到person對象並顯示.
com/amos/android_db/MyActivity.java
復制代碼
package com.amos.android_db;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import com.amos.android_db.dao.Person;
import com.amos.android_db.dao.PersonDao;
import java.util.List;
public class MyActivity extends Activity {
private ListView personListView;
private List<Person> persons;
LayoutInflater inflater;//打氣筒
String tag="MyActivity.class";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//inflater是一個系統服務,初始化系統服務,利用inflater將一個布局文件轉化為一個對象
inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
setContentView(R.layout.main);
PersonDao personDao = new PersonDao(this);
persons = personDao.findAll();
//第一步,得到組件的id的引用
personListView = (ListView) this.findViewById(R.id.listview_show_data);
//第二步,設置組件要顯示的內容,listview要顯示的內容比較復雜,需要數據的適配器
personListView.setAdapter(new MyListAdapter());
//注冊點擊事件
personListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
/**
*
* @param parent 當前ListView
* @param view 代表當前被點擊的條目
* @param position 當前條目的位置
* @param id 當前被點擊的條目的id
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(tag,"點擊了!");
/*
方法 1:
*/
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
Toast.makeText(MyActivity.this,"姓名是1:"+tv_name.getText(),Toast.LENGTH_SHORT).show();
/*
方法 2:
*/
String name = persons.get(position).getName();
Toast.makeText(MyActivity.this,"姓名是2:"+name,Toast.LENGTH_SHORT).show();
/*
方法 3:
*/
Person p=(Person)parent.getItemAtPosition(position);
Toast.makeText(MyActivity.this,"姓名是3:"+p.getName(),Toast.LENGTH_SHORT).show();
}
});
}
public class MyListAdapter extends BaseAdapter {
/**
* 返回當前有多少個條目
* @return
*/
@Override
public int getCount() {
return persons.size();
}
/**
* 返回當前position位置對應的條目的object對象
* @param position
* @return
*/
@Override
public Object getItem(int position) {
return persons.get(position);
}
/**
* 返回當前position位置對應條目的id
* @param position
* @return
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* 返回一個條目顯示的具體內容
* 計算當前界面 會有多少個條目出現
* 1.得到每一個textview的高度
* 2.得到listview的高度
* 3.listview高度/textview高度=得到了一個屏幕顯示textview的的個數
* listview的每一個條目的顯示都需要調用一次getView的方法
* 屏幕上有多個item顯示就會調用多少getview的方法
*
* @param position
* @param convertView
* @param parent
* @return
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TextView textView = new TextView(MyActivity.this);
// textView.setText(persons.get(position).getName()+":"+persons.get(position).getAge());
// return textView;
View view = inflater.inflate(R.layout.item, null);
Person person = persons.get(position);
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
TextView tv_age = (TextView) view.findViewById(R.id.tv_age);
tv_name.setText("姓名:" + person.getName());
tv_age.setText("年齡:" + person.getAge());
Log.d("item:",""+position);
return view;
}
}
}
復制代碼
2.simpleAdapter的使用
復制代碼
//第二步,設置組件要顯示的內容,listview要顯示的內容比較復雜,需要數據的適配器
// personListView.setAdapter(new MyListAdapter());//自實現BaseAdapter
List<Map<String, String>> data = new ArrayList<Map<String, String>>();
for (Person p : persons) {
Map<String, String> datavalue = new HashMap<String, String>();
datavalue.put("name", p.getName());
datavalue.put("age", p.getAge().toString());
data.add(datavalue);
}
personListView.setAdapter(new SimpleAdapter(this, data, R.layout.item, new String[]{"name", "age"}, new int[]{R.id.tv_name, R.id.tv_age}));
復制代碼
之前的適配器是繼承BaseAdapter,實現了getCount(),getItem(int position),getItemId(int position),getView(int position, View convertView, ViewGroup parent)方法,這裡調用SimpleAdapter方法,查看SimpleAdapter的實現也可以發現其也是繼承了BaseAdapter類.
SimpleAdapter(android.content.Context context, java.util.List<? extends java.util.Map<java.lang.String, ?>> data, int resource, java.lang.String[] from, int[] to) { throw new RuntimeException("Stub!"); }
context表示上下文,data表示要顯示的內容,resource表示資源文件的id,from這裡表示的是map裡的key,然後其id依次相對應為tv_name,和tv_age.
3.ArrayAdapter的使用
復制代碼
//3)arrayAdapter
// public ArrayAdapter(android.content.Context context, int resource, int textViewResourceId, T[] objects) { throw new RuntimeException("Stub!"); }
String[] personArray = new String[persons.size()];
for(int i=0;i<persons.size();i++){
personArray[i] = persons.get(i).getName();
}
personListView.setAdapter(new ArrayAdapter(this,R.layout.item,R.id.tv_name,personArray));
復制代碼
這裡顯示的只是一側的內容,R.id.tv_name,這裡只顯示姓名,ArrayAdapter適合只有一列內容的數據顯示.
4.SimpleCursoAdapter的使用
//4)simpleCursorAdapter
//要求數據的組件名稱以下劃線
Cursor cursor = personDao.findAllByCursor() ;
personListView.setAdapter(new SimpleCursorAdapter(this,R.layout.item,cursor,new String[]{"name","age"},new int[]{R.id.tv_name,R.id.tv_age}));
PersonDao.java中增加一個方法用來返回cursor結果集.
public Cursor findAllByCursor(){
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor=null;
if (db.isOpen()) {
cursor = db.query("person", null, null, null, null, null, null);
}
運行時出現的問題:
復制代碼
06-16 18:11:25.106 485-485/com.amos.android_db E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.amos.android_db/com.amos.android_db.MyActivity}: java.lang.IllegalArgumentException: column '_id' does not exist
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)
at android.widget.CursorAdapter.init(CursorAdapter.java:111)
at android.widget.CursorAdapter.<init>(CursorAdapter.java:90)
at android.widget.ResourceCursorAdapter.<init>(ResourceCursorAdapter.java:47)
at android.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:84)
at com.amos.android_db.MyActivity.onCreate(MyActivity.java:69)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
復制代碼