在Android的Listview中顯示多種視圖

來源:互聯網
上載者:User

1.情境

  在使用ListView時,我們經常遇到需要在一個ListView中顯示多種視圖的情境,例如:聊天軟體的聊天介面中,自己發送的訊息在左邊顯示自己的頭像,別人發送的訊息在右邊顯示別人的頭像,等等。

2.ListView常用方式
      2.1 ListView常用的Adapter有:ArrayAdapter,SimpleAdapter,CursorAdapter。在android sdk sample的ApiDemo工程中有詳細的使用方法。

      2.2 當我們需要在ListView的視圖中展示複雜的資料和資源,處理複雜的事件時,我們可以繼承BaseAdapter,重寫BaseAdapter中的方法來達到目的,主要是getView(int position, View convertView, ViewGroup parent)方法。在android sdk sample的ApiDemo工程中有詳細的使用方法。

      2.3 當我們需要在ListView中顯示多種視圖時,仍然使用繼承BaseAdapter的方式,要注意的是getItemViewType(int position)和getViewTypeCount()這兩個方法。

3.ListView中顯示多種視圖的實現方式
      3.1 實現步驟
            3.1.1 定義試圖類型常量
            我們定義了三種:

/** * 發送的訊息 */private static final int TYPE_SEND = 0;/** * 收到的訊息 */private static final int TYPE_RECEIVE = TYPE_SEND + 1;/** * 圖片 */private static final int TYPE_PIC = TYPE_RECEIVE + 1;

            3.1.2 重寫getItemViewType(int position)和getViewTypeCount()方法

public int getItemViewType(int position) {int type = super.getItemViewType(position);try{type = Integer.parseInt(data.get(position).get("type"));} catch (Exception e){e.printStackTrace();}System.out.println("getItemViewType::" + position + " is " + type);return type;}public int getViewTypeCount() {System.out.println("getViewTypeCount is " + 3);return 3;}

由getItemViewType返回對應項的自訂檢視類型,getViewTypeCount返回檢視類型總數。
        注意:getViewTypeCount返回的值必須比檢視類型常量值大,以數組來比喻的話,getViewTypeCount返回的是數組的長度,getItemViewType返回的(即3.1.1中定義的常量)就是數組的下標。
            3.1.2 重寫getView方法

public View getView(int position, View convertView, ViewGroup parent) {System.out.println("getView::" + position);int type = TYPE_SEND;try{type = Integer.parseInt(data.get(position).get("type"));} catch (Exception e){e.printStackTrace();}ViewHolder holder = null;if (convertView == null){System.out.println("getView::convertView is null");holder = new ViewHolder();switch (type){case TYPE_SEND:convertView = View.inflate(getBaseContext(),R.layout.listitem_send, null);holder.text = (TextView) convertView.findViewById(R.id.message);break;case TYPE_RECEIVE:convertView = View.inflate(getBaseContext(),R.layout.listitem_receive, null);holder.text = (TextView) convertView.findViewById(R.id.message);break;case TYPE_PIC:convertView = new ImageView(getBaseContext());((ImageView) convertView).setImageResource(R.drawable.icon);break;}convertView.setTag(holder);}else{System.out.println("getView::convertView not null");holder = (ViewHolder) convertView.getTag();}if (type != TYPE_PIC){String msg = data.get(position).get("content");holder.text.setText(msg);}return convertView;}

      這一部分和2.2是差不多的,不同的地方在於當convertView為空白時,需要根據當前項資料對應的檢視類型初始化相應的視圖布局。其他像getCount,getItem方法照例重寫。
      
     

      3.2 過程分析

        在ListView的父類AbsListView中,有一個變數RecycleBin mRecycler,用來儲存某一顯示項目布局對應的視圖。實際儲存在ArrayList<View>[]中,該數組的長度為getViewTypeCount的傳回值。RecycleBin
是AbsListView的一個內部類。
 
當ListView執行setAdapter方法時,mRecycler會重設,getViewTypeCount方法會被調用。       

        當ListView要顯示某一項時,getItemViewType方法被調用,根據傳回值在mRecycler搜尋得到緩衝的視圖。這也是為什麼getViewTypeCount傳回值要比定義的檢視類型常量值大的原因,否則會導致數組越界異常。
 
  然後調用getView方法,緩衝的視圖被傳遞給getView方法的convertView形參(詳細可以參考AbsListView的obtainView方法)。
        當傳遞進來的convertView形參為null的話,需要根據該項的檢視類型,初始化布局。

  最後給顯示項目填充資料。

下載源碼:

http://download.csdn.net/detail/clarketang/3694460

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.