閱讀264 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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的概念和使用會在下一節中介紹。
 


圖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: 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
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, mStrings));
        getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
    public void onItemClick(AdapterView<?> parent, View v, int pos,
    long id) {
        Toast.makeText(ListView_1.this, mStrings[pos],
Toast.LENGTH_SHORT).show();
    }
    });
    }

    private String[] mStrings = {
            "北京市", "天津市", "上海", "重慶", "烏魯木齊", …};
}
查看代碼不難發現這裏沒有使用布局文件,那就意味著不需要使用R文件來獲得控件,所以在程序中使用了getListView()方法來獲得ListView控件。處理ListView的項目點擊事件有兩種方法,一種是通過與ListView對象設置setOnItemClickListener方式實現,代碼如下:
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
     @Override
    public void onItemClick(AdapterView<?> parent, View v, int pos,
    long id) {
        Toast.makeText(ListView_1.this, mStrings[pos],
Toast.LENGTH_SHORT).show();
}
});
另外一種是覆蓋ListActivity的onListItemClick(ListView l, View v, int position, long id)方法實現,代碼如下所示。
@Override
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所示。
 


圖6-9 自定義adapter
相關程序代碼請參考代碼清單6-6:
【代碼清單6-6】 chapter6_3/src/com/work/ListViewIcon_3.java
public class ListViewIcon_3 extends ListActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        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);
            break;
          …
            default:
            holder.icon.setImageBitmap(mIcon0);
            break;
            }
           

            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開發案例驅動教程》第六章


最後更新:2017-04-02 06:51:43

  上一篇:go cygwin粘貼複製操作
  下一篇:go Android多媒體開發--資源文件播放