天天看點

ListView分頁(帶圖檔)顯示用法案例

listview是android中最為常用的清單類型控件,listview中的選擇項目中樣式很多有的是純文字的、有的還可以帶有圖檔。它的繼承關系如下:

java.lang.object

   ↳ android.view.view

     ↳ android.view.viewgroup

       ↳ android.widget.adapterview<t extends android.widget.adapter>

         ↳ android.widget.abslistview

           ↳ android.widget.listview

android.widget.listview繼承了android.view.viewgroup。

首先看一個純文字的listview例子,案例運作後會出現一個城市清單如圖6-8所示,選擇某個城市,彈出一個toast,關于toast的概念和使用會在下一節中介紹。

ListView分頁(帶圖檔)顯示用法案例

圖6-8 listview

程式代碼請參考代碼清單6-4:

【代碼清單6-4】 chapter6_3/src/com/work/listview_1_activity.java

public class listview_1_activity extends activity {

private listview listview;

@override

    public void oncreate(bundle savedinstancestate) {

        super.oncreate(savedinstancestate);

        setcontentview(r.layout.listview_activity);

        listview = (listview)findviewbyid(r.id.listview01);

        arrayadapter<string> adapter = new arrayadapter<string>(this,

                android.r.layout.simple_list_item_1, mstrings);

        listview.setadapter(adapter);

   listview.setonitemclicklistener(new adapterview.onitemclicklistener() {

        @override

    public void onitemclick(adapterview<?> parent, view v, int pos,

    long id) {

        toast.maketext(listview_1_activity.this, mstrings[pos],

toast.length_short).show();

    }

    });

    }

    private string[] mstrings = {

            "北京市", "天津市", "上海", "重慶", "烏魯木齊", …};

}

對于arrayadapter應該已經很熟悉了,其中的android.r.layout.simple_list_item_1是使用系統的布局樣式。android系統本身提供了很多的這樣的布局檔案,但是有的适合于listview控件,有的适合于spinner控件,有的适合于它的清單控件,這是使用時需要注意的。

在這種方式下,需要在布局檔案listview_activity.xml中添加listview控件:

<listview android:id="@+id/listview01" android:layout_width="wrap_content"

android:layout_height="wrap_content"></listview>

由于listview在android中是很常用的清單類型控件,隻要是有多條資訊需要顯示的時候都可以考慮使用listview展示出來,正是由于listview使用的普遍,是以android又提供了一個清單類型的activity——listactivity,來簡化listview開發。

通過繼承listactivity類而實作一個簡單的listview功能,而不要直接使用listview控件。同樣上面案例如果使用listactivity請參考代碼清單6-5的寫法:

【代碼清單6-5】 chapter6_3/src/com/work/listview_1.java

public class listview_1 extends listactivity {

    /** called when the activity is first created. */

    @override

        setlistadapter(new arrayadapter<string>(this,

                android.r.layout.simple_list_item_1, mstrings));

        getlistview().setonitemclicklistener(new adapterview.onitemclicklistener() {

        toast.maketext(listview_1.this, mstrings[pos],

檢視代碼不難發現這裡沒有使用布局檔案,那就意味着不需要使用r檔案來獲得控件,是以在程式中使用了getlistview()方法來獲得listview控件。處理listview的項目點選事件有兩種方法,一種是通過與listview對象設定setonitemclicklistener方式實作,代碼如下:

getlistview().setonitemclicklistener(new adapterview.onitemclicklistener() {

     @override

});

另外一種是覆寫listactivity的onlistitemclick(listview l, view v, int position, long id)方法實作,代碼如下所示。

protected void onlistitemclick(listview l, view v, int position, long id) {

toast.maketext(listview_1.this, mstrings[position], toast.length_short)

.show();

再看一個自定義adapter的例子,這是一個帶有圖示的listview,程式運作結果如圖6-9所示。

ListView分頁(帶圖檔)顯示用法案例

圖6-9 自定義adapter

相關程式代碼請參考代碼清單6-6:

【代碼清單6-6】 chapter6_3/src/com/work/listviewicon_3.java

public class listviewicon_3 extends listactivity {

        setlistadapter(new efficientadapter(this));

    private static final string[] data = {

    "北京市", "天津市", "上海", "重慶", "哈爾濱",

         "石家莊", "秦皇島", "濟南", "青島", "南京",

         "三亞", "昆明", "成都", "長沙", "武漢",

         "九江", "香港", "澳門","蘭州","張家口" };

自定義的adapter是efficientadapter,efficientadapter的相關代碼請參考代碼清單6-7:

【代碼清單6-7】 chapter6_3/src/com/work/listviewicon_3.java

private static class efficientadapter extends baseadapter {

        private layoutinflater minflater;

        private bitmap micon0;

        private bitmap micon1;

…  …

        public efficientadapter(context context) {

            minflater = layoutinflater.from(context);

            micon0 = bitmapfactory.decoderesource(context.getresources(), r.drawable.noicon);

            micon1 = bitmapfactory.decoderesource(context.getresources(), r.drawable.beijing);

…   …

      }

        public int getcount() {

            return data.length;

        }

        public object getitem(int position) {

            return data[position];

        public long getitemid(int position) {

            return position;

        public view getview(int position, view convertview, viewgroup parent) {

            viewholder holder;

            if (convertview == null) {

                convertview = minflater.inflate(r.layout.main, null);

                holder = new viewholder();

                holder.text = (textview) convertview.findviewbyid(r.id.textview);

                holder.icon = (imageview) convertview.findviewbyid(r.id.icon);

                convertview.settag(holder);

            } else {

                holder = (viewholder) convertview.gettag();

            }

            holder.text.settext(data[position]);

            switch(position)

            {

            case 0:

            holder.icon.setimagebitmap(micon1);

            break;

            case 1:

            holder.icon.setimagebitmap(micon2);

          …

            default:

            holder.icon.setimagebitmap(micon0);

            return convertview;

        static class viewholder {

            textview text;

            imageview icon;

編寫自定義adapter可以繼承baseadapter類,如果是資料庫使用可以繼承cursoradapter。在本例中繼承了baseadapter類,baseadapter是一個抽象類,必須在它的子類中實作下面的方法:

• int getcount() 傳回總資料源中總的記錄數;

• object getitem(int position) 根據選擇的項目的位置,獲得選擇的資料源中某個項目的資料;

• long getitemid(int position) 根據選擇的項目的位置;

• view getview(int position, view convertview, viewgroup parent) 獲得要展示的項目view對象。

這裡最為麻煩的方法就是getview(),getview()方法是listview的每個清單項目繪制在螢幕上時被調用。該方法其中的一個參數是convertview,在listview第一次顯示清單項目的時候,convertview是null值。當向上滑動螢幕時候,螢幕上面的清單項目退出螢幕,螢幕下面原來不可見的清單項目會進入螢幕,這個時候的convertview不是null值,下面代碼的處理對于提供listview控件提高性能是至關重要的。

if (convertview == null) {

convertview = minflater.inflate(r.layout.main, null);

holder = new viewholder();

holder.text = (textview) convertview

.findviewbyid(r.id.textview);

holder.icon = (imageview) convertview.findviewbyid(r.id.icon);

convertview.settag(holder);

} else {

holder = (viewholder) convertview.gettag();

隻有在convertview為null時才去執行個體化控件,建立convertview對象、holder對象,其中convertview對象是通過minflater.inflate(r.layout.main, null)方法,從一個main.xml布局檔案中加載并建立的。

而在convertview非null的時候不會執行個體化控件,否則每次都要執行個體化控件,當清單項目很多時,使用者反複滑動螢幕會有“卡”的感覺,不再流暢了。

viewholder類是将每一個項目中的控件封裝起來的類,可以在convertview 為null時候建立viewholder類的執行個體holder,然後通過convertview.settag(holder);把它放到convertview中,而在convertview非null時候,再通過convertview.gettag()過的一個viewholder類的執行個體,這樣在翻屏的時候就不會反複建立viewholder執行個體對象了,就本例而言隻是建立了9個viewholder執行個體。

                                                                                       出自《android開發案例驅動教程》第六章

繼續閱讀