今天學習點輕松的內容吧,看看android.app包裡的幾個類。首先是這個在平台自的例子中被廣泛使用的ListActivity。這個類其實就是一個含有一個ListView組件的Activity類。也就是說,如果我們直接在一個普通的Activity中自己加一個ListVIEw也是完全可以取代這個ListActivity的,只是它更方便而已,方便到什麼程度呢?來做個例子瞧瞧。
public class HelloTwoB extends ListActivity...{
public void onCreate(Bundle icicle) ...{
super.onCreate(icicle);
setTheme(android.R.style.Theme_Dark);
setContentVIEw(R.layout.mainb);
List items = fillArray();
ArrayAdapter adapter = new ArrayAdapter(this,R.layout.list_row,items);
this.setListAdapter(adapter);
}
private List fillArray() ...{
List items = new ArrayList();
items.add("日曜日");
items.add("月曜日");
items.add("火曜日");
items.add("水曜日");
items.add("木曜日");
items.add("金曜日");
items.add("土曜日");
return items;
}
@Override
protected void onListItemClick(ListView l, VIEw v, int position, long id)
...{
TextView txt = (TextView)this.findVIEwById(R.id.text);
txt.setText("あすは "+l.getSelectedItem().toString()+"です。");
}
}
的確可以簡單到只需准備一個List對象並借助Adapter就可以構造出一個列表。重載onListItemClick方法可以響應選擇事件,利用第一個參數可以訪問到這個ListView實例以得到選中的條目信息。這裡有一點要說明的,就是如果更簡單的話,其實連那個setContentVIEw都可以不要了,android也會自動幫我們構造出一個全屏的列表。但是本例中我們需要一個TextVIEw來顯示選中的條目,所以我們需要一個layout.mainb描述一下這個列表窗口。
XML version="1.0" encoding="utf-8"?>
android:orIEntation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
/>
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:drawSelectorOnTop="false"
/>
LinearLayout>
這裡需要注意的是那個ListVIEw的ID,是系統自定義的android:list,不是我們隨便取的,否則系統會說找不到它想要的listview了。然後,在這個listview之外,我們又增加了一個TextVIEw,用來顯示選中的條目。
再來說說這裡用到的ArrayAdapter,它的構造函數中第二個參數是一個資源ID,ArrayAdapter的API文檔中說是要求用一個包含TextVIEw的layout文件,平台用它來顯示每個選擇條目的樣式,這裡的取值是R.layout.list_row,所以,我們還有一個list_row.XML文件來描述這個布局,相當簡單。
XML version="1.0" encoding="utf-8"?>
android:orIEntation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
XMLns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
XMLns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
LinearLayout>
從ArrayAdapter上溯到BaseAdapter,發現還有幾個同源的Adapter也應該可以使用,象SimpleAdapter和CursorAdapter,還是做個例子來實驗一下吧。
先看看SimpleAdapter,說是simple卻不simple。
首先看看這個fillMaps方法,基本上就明白這個simpleAdapter是怎麼回事了,在有些場合它還是挺有用的,可以為每個條目綁定一個值:
private List> fillMaps()
...{
List> items = new ArrayList>();
HashMap i = new HashMap();
i.put("name","日曜日");
i.put("key", "SUN");
items.add(i);
HashMap i1 = new HashMap();
i1.put("name","月曜日");
i1.put("key", "MON");
items.add(i1);
HashMap i2 = new HashMap();
i2.put("name","火曜日");
i2.put("key", "TUE");
items.add(i2);
HashMap i3 = new HashMap();
i3.put("name","水曜日");
i3.put("key", "WED");
items.add(i3);
HashMap i4= new HashMap();
i4.put("name","木曜日");
i4.put("key", "THU");
items.add(i4);
HashMap i5 = new HashMap();
i5.put("name","金曜日");
i5.put("key", "FRI");
items.add(i5);
HashMap i6 = new HashMap();
i6.put("name","土曜日");
i.put("key", "SAT");
items.add(i6);
return items;
}
然後,在HelloTwoB中的onCreate函數中,修改代碼,有幾個不同:items的元素是HashMap實例,這是一點變化,然後構造函數除了要求items以外,還要求提供一個string[]來說明用hash表中的哪個字段顯示在列表中,而後是一個資源ID的數組。我的代碼是這樣的:
//SimpleAdapter demo
List> items = fillMaps();
SimpleAdapter adapter=new SimpleAdapter(this,items,R.layout.list_row,new String[]...{"name"},new int[]...{R.id.item});
編譯跑一下可以看到結果了,是吧?只是顯示的文字不太對,再改一下:
protected void onListItemClick(ListView l, VIEw v, int position, long id)
...{
TextView txt = (TextView)this.findVIEwById(R.id.text);
txt.setText("あすは "+((HashMap)l.obtainItem(position)).get("key").toString()+"です。");
}
這樣就好多了,其實一般情況下我們都是用ListVIEw中的obtainItem取得當前選中的條目,然後轉成List中的對應類型來使用的。
上面的例子中只顯示name對應的值,其實你也可以試一下這樣:
SimpleAdapter adapter=new SimpleAdapter(this,items,R.layout.list_row,new String[]...{"name","key"},new int[]...{R.id.item,R.id.item2});
看看是什麼效果。
再看看那個CursorAdapter吧,它的列表中元素要求是Cursor,這東西與DB有關,不過最簡單的DB就是通訊簿。先從Contacts.People入手吧,同樣修改代碼:
//CursorAdapter demo
Cursor mCursor = this.getContentResolver().query(Contacts.People.CONTENT_URI, null, null, null, null);
SimpleCursorAdapter adapter=new SimpleCursorAdapter(this,R.layout.list_row,mCursor,new String[]...{Contacts.People.NAME},new int[]...{R.id.item});
因為單純的CursorAdapter是抽象類,所以我用的是它的子類SimpleCursorAdapter,很好理解,先用ContentResolver查詢通訊簿得到一個游標,然後告訴SimpleCursorAdapter要用其中的People.NAME作為顯示項來構造出一個adapter即可。
現在的onListItemClick也不一樣了,如下:
protected void onListItemClick(ListView l, VIEw v, int position, long id)
...{
TextView txt = (TextView)this.findVIEwById(R.id.text);
Cursor c = (Cursor)l.obtainItem(position);
txt.setText("SEL = "+c.getString(c.getColumnIndex(Contacts.People.NUMBER)));
}
這裡同樣是先用obtainItem取到游標,然後用從記錄中取出想要的字段顯示即可。在做這個例子時,因為權限的問題我們還得修改一下androidManifest.XML文件,讓我們的應用可以訪問到通訊簿:
manifest XMLns:android="http://schemas.android.com/apk/res/android"
package="cn.sharetop.android.hello.two">
uses-permission id="android.permission.READ_CONTACTS" />
application android:icon="@drawable/icon">
... ...