【Android遊戲開發二十三】自定義ListView【通用】適配器並實現監聽控件!


 李華明Himi 原創,轉載務必在明顯處註明:
轉載自 【黑米GameDev街區】 原文連接:  http://www.himigame.com/android-game/374.html


  ListView :在Android應用開發過程當中屬於最經常使用的系統組件之一,固然可能童鞋們問爲何會忽然遊戲開發中講這個,呵呵,其實在遊戲開發中,也會經常使用到系統組件,好比遊戲排行榜,簡單的遊戲關卡選擇等等,均可以來使用ListView來實現;css

    固然關於ListView我想你們都會使用了,那麼這篇文章也不是跟你們講解ListView是若是使用的,而是如何實現自定義一個【通用】適配器類;html

    在ListView三種適配器當中,最受你們青睞的確定就是SimpleAdapter適配器,用過的童鞋們都很清楚,它的擴展性很強,能夠將ListView中每一項都使用自定義佈局,插入N多組件;可是SimpleAdapter也有弱點,那就是當ListView中每一項有Button、CheckBox等這些有事件的組件,咱們想監聽它們就必須自定義適配器!那麼今天的重點也就是來說解一下如何寫一個自定義通用適配器類!java

    SimpleAdapter 構造的時候,咱們知道須要五個參數來進行映射數據到ListView中,那麼咱們今天的自定義通用適配器其實也就是實現系統SimpleAdapter的一個自定義版;android

    OK,可能我說這麼多,你們仍是不太懂,其實今天要講述的自定義通用適配器優勢有三點:app

    1.使用通用適配器就不須要每次使用自定義適配器的時候,都要去從新去寫一個,太累。。。。ide

    2.構造方法與SimpleAdapter構造方法相同,五個參數也一摸同樣!佈局

    3.只須要在自定義的適配器類中,將咱們須要監聽的組件進行設置監聽便可!別的代碼不須要去改動!學習


例如咱們須要完成下圖這種ListView:ui

(圖1)this


首先咱們來完成ListView中每項的佈局:

main.xml:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/iv" /> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:id="@+id/bigtv" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="10sp" android:id="@+id/smalltv" /> </LinearLayout> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button" android:id="@+id/btn" /> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cb" /> </LinearLayout> 
 


修改源碼:MainActivity.java:

public class MainActivity extends Activity { private SimpleAdapter adapter;// 聲明適配器對象 private ListView listView; // 聲明列表視圖對象 private List<Map<String, Object>> list;// 聲明列表容器 public static MainActivity ma; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ma = this; // 實例化列表容器 list = new ArrayList<Map<String, Object>>(); listView = new ListView(this);// 實例化列表視圖 // 實例一個列表數據容器 Map<String, Object> map = new HashMap<String, Object>(); // 往列表容器中添加數據 map.put("item1_imageivew", R.drawable.icon); map.put("item1_bigtv", "BIGTV"); map.put("item1_smalltv", "SMALLTV"); // 將列表數據添加到列表容器中 list.add(map); // --使用系統適配器,沒法實現組件監聽; // //實例適配器 adapter = new SimpleAdapter(this, list, R.layout.main, new String[] { "item1_imageivew", "item1_bigtv", "item1_smalltv" }, new int[] { R.id.iv, R.id.bigtv, R.id.smalltv }); listView.setAdapter(adapter); // //顯示列表視圖 this.setContentView(listView); } }

到此,咱們以前要求完成的(圖1)要求的ListView,[對ListView不太熟悉的童鞋自行百度google先學習一下基礎吧]

固然這裏咱們只是完成了界面,若是想監聽(圖1)中的按鈕和複選框事件,那麼咱們確定須要自定義一個適配器,那麼下面開始介紹如何實現通用適配器:

建立一個新類,類名:「MySimpleAdapter.java」繼承BaseAdapter:

/** * */ package com.himi; import java.util.List; import java.util.Map; import android.app.AlertDialog; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.TextView; import android.widget.CompoundButton.OnCheckedChangeListener; /** * @author Himi * */ public class MySimpleAdapter extends BaseAdapter { private LayoutInflater mInflater; private List<Map<String, Object>> list; private int layoutID; private String flag[]; private int ItemIDs[]; public MySimpleAdapter(Context context, List<Map<String, Object>> list, int layoutID, String flag[], int ItemIDs[]) { this.mInflater = LayoutInflater.from(context); this.list = list; this.layoutID = layoutID; this.flag = flag; this.ItemIDs = ItemIDs; } @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return 0; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = mInflater.inflate(layoutID, null); for (int i = 0; i < flag.length; i++) {//備註1 if (convertView.findViewById(ItemIDs[i]) instanceof ImageView) { ImageView iv = (ImageView) convertView.findViewById(ItemIDs[i]); iv.setBackgroundResource((Integer) list.get(position).get( flag[i])); } else if (convertView.findViewById(ItemIDs[i]) instanceof TextView) { TextView tv = (TextView) convertView.findViewById(ItemIDs[i]); tv.setText((String) list.get(position).get(flag[i])); }else{ //...備註2 } } addListener(convertView); return convertView; } /** * 童鞋們只須要將須要設置監聽事件的組件寫在下面這方法裏就能夠啦! * 別的不須要修改! * 備註3 */ public void addListener(View convertView) { ((Button)convertView.findViewById(R.id.btn)).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { new AlertDialog.Builder(MainActivity.ma) .setTitle("自定義通用SimpleAdapter") .setMessage("按鈕成功觸發監聽事件!") .show(); } }); ((CheckBox)convertView.findViewById(R.id.cb)). setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { new AlertDialog.Builder(MainActivity.ma) .setTitle("自定義通用SimpleAdapter") .setMessage("CheckBox成功觸發狀態改變監聽事件!") .show(); } }); } }


備註1:這個For循環中是對ListView中每一項中包含全部的組件進行斷定每一個組件的類型,從而去設置其數據!

其中 《instanceof》這個關鍵字可能有的童鞋不太熟習,這個是對Object 類型的判斷;

這裏我只是對ImageView、TextView的類型進行的數據識別,爲何我這裏只寫了這兩種,那是由於Button、CheckBox等這些帶事件響應的組件是沒法經過適配器映射到ListView上的;


其實關於適配器映射的機制,這裏簡單說下:例如一個TextView組件,那麼在ListView的每一項(List)中put()添加的時候,put()方法中第一個參數key你們知道是用於與適配器進行對應映射數據用的值,那麼第二個參數其實就是put進組件的數據;其實當其數據反射在ListViw時,其實內部就是對組件進行實例化,而且對組件設置數據;



備註2 :我這裏最後還有一個else{...}這裏是留給童鞋們去擴展的,由於可能還有一些其餘能映射的組件,因此這裏留下接口,供你們擴展;


備註3:addListener(View convertView)這是我留出來的方法,童鞋們只須要將須要設置監聽事件的組件寫在這方法裏就能夠啦!


那麼看一下咱們使用通用監聽器的效果吧:


 


OK,很正常!那麼在來看看使用系統的SimpleAdapter 與咱們自定義的MySimpleAdapter代碼對比圖:


怎麼樣!構造參數徹底同樣,並且咱們這個比它強大,咱們只要去設置下須要監聽的組件監聽代碼就OK了。

娃哈哈,好啦,今天就到這裏吧,但願此通用適配器對你們有用!

補充:你們使用自定義適配器的時候,有時候ListView每一項的焦點沒有了,好比本文中是由於Button和CheckBox截獲了焦點,童鞋們只要將button和checkBox的焦點設置不可見就OK啦。~

  xml中focusable是這個屬性;    android:focusable="false"

這裏也提醒一下開發遊戲的童鞋們,不少遊戲開發者認爲開發遊戲不用去學習系統組件的使用,不用去沾染xml、佈局啥的,其實這麼想的童鞋們大家就大錯特錯了,Android之因此能這麼火,其組件的美觀佔了很重的分量,這麼美的組件不用豈不是很浪費!!但願童鞋們對組件不熟悉的遊戲開發者都要去學習學習下組件的使用!


源碼下載http://www.himigame.com/android-game/374.html





 


原文連接: http://blog.csdn.net/xiaominghimi/article/details/6314704
相關文章
相關標籤/搜索