【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
相关文章
相关标签/搜索