【Android游戏开发二十三】自定义ListView【通用】适配器并实现监听控件!

简介:

   ListView :在Android应用开发过程中属于最常用的系统组件之一,当然可能童鞋们问为什么会突然游戏开发中讲这个,呵呵,其实在游戏开发中,也会常常使用到系统组件,比如游戏排行榜,简单的游戏关卡选择等等,都可以来使用ListView来实现;

    当然关于ListView我想大家都会使用了,那么这篇文章也不是跟大家讲解ListView是如果使用的,而是如何实现自定义一个【通用】适配器类;

    在ListView三种适配器当中,最受大家青睐的肯定就是SimpleAdapter适配器,用过的童鞋们都很清楚,它的扩展性很强,可以将ListView中每一项都使用自定义布局,插入N多组件;但是SimpleAdapter也有弱点,那就是当ListView中每一项有Button、CheckBox等这些有事件的组件,我们想监听它们就必须自定义适配器!那么今天的重点也就是来讲解一下如何写一个自定义通用适配器类!

    SimpleAdapter 构造的时候,我们知道需要五个参数来进行映射数据到ListView中,那么我们今天的自定义通用适配器其实也就是实现系统SimpleAdapter的一个自定义版;

    OK,可能我说这么多,大家还是不太懂,其实今天要讲述的自定义通用适配器优点有三点:

    1.使用通用适配器就不需要每次使用自定义适配器的时候,都要去重新去写一个,太累。。。。

    2.构造方法与SimpleAdapter构造方法相同,五个参数也一摸一样!

    3.只需要在自定义的适配器类中,将我们需要监听的组件进行设置监听即可!别的代码不需要去改动!

例如我们需要完成下图这种ListView:(图1) 

首先我们来完成ListView中每项的布局:

main.xml: 


     
     
  1. <?xml version="1.0" encoding="utf-8"?>     
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     
  3.     android:orientation="horizontal"     
  4.     android:layout_width="fill_parent"     
  5.     android:layout_height="fill_parent"     
  6.     >     
  7. <ImageView       
  8.     android:layout_width="wrap_content"       
  9.     android:layout_height="wrap_content"       
  10.     android:id="@+id/iv"     
  11.     />       
  12.    <LinearLayout     
  13.         android:orientation="vertical"     
  14.         android:layout_width="wrap_content"     
  15.         android:layout_height="wrap_content"     
  16.         >     
  17.         <TextView        
  18.             android:layout_width="wrap_content"       
  19.             android:layout_height="wrap_content"       
  20.             android:textSize="20sp"     
  21.             android:id="@+id/bigtv"     
  22.             />     
  23.         <TextView        
  24.             android:layout_width="wrap_content"       
  25.             android:layout_height="wrap_content"       
  26.             android:textSize="10sp"     
  27.             android:id="@+id/smalltv"     
  28.             />     
  29.     </LinearLayout>     
  30. <Button        
  31.     android:layout_width="wrap_content"       
  32.     android:layout_height="wrap_content"       
  33.      android:text="button"     
  34.     android:id="@+id/btn"     
  35.     />     
  36. <CheckBox        
  37.    android:layout_width="wrap_content"       
  38.    android:layout_height="wrap_content"       
  39.    android:id="@+id/cb"     
  40.    />     
  41. </LinearLayout>     
 修改源码:MainActivity.java: 

      
      
  1. public class MainActivity extends Activity {  
  2.     private SimpleAdapter adapter;// 声明适配器对象  
  3.     private ListView listView; // 声明列表视图对象  
  4.     private List<Map<String, Object>> list;// 声明列表容器  
  5.     public static MainActivity ma;  
  6.     @Override  
  7.     public void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.         ma = this;  
  10.         // 实例化列表容器  
  11.         list = new ArrayList<Map<String, Object>>();  
  12.         listView = new ListView(this);// 实例化列表视图  
  13.         // 实例一个列表数据容器  
  14.         Map<String, Object> map = new HashMap<String, Object>();  
  15.         // 往列表容器中添加数据  
  16.         map.put("item1_imageivew", R.drawable.icon);  
  17.         map.put("item1_bigtv", "BIGTV");  
  18.         map.put("item1_smalltv", "SMALLTV");  
  19.         // 将列表数据添加到列表容器中  
  20.         list.add(map);  
  21.         // --使用系统适配器,无法实现组件监听;  
  22.         // //实例适配器  
  23.         adapter = new SimpleAdapter(this, list, R.layout.main, new String[] {  
  24.                 "item1_imageivew", "item1_bigtv", "item1_smalltv" }, new int[] {  
  25.                 R.id.iv, R.id.bigtv, R.id.smalltv });  
  26.         listView.setAdapter(adapter);  
  27.         // //显示列表视图  
  28.         this.setContentView(listView);  
  29.     }  
        到此,我们之前要求完成的(图1)要求的ListView,[对ListView不太熟悉的童鞋自行百度google先学习一下基础吧]
    当然这里我们只是完成了界面,如果想监听(图1)中的按钮和复选框事件,那么我们肯定需要自定义一个适配器,那么下面开始介绍如何实现通用适配器:
    创建一个新类,类名:“MySimpleAdapter.java”继承BaseAdapter:  

         
         
  1. /**  
  2.  *   
  3.  */ 
  4. package com.himi;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7. import android.app.AlertDialog;  
  8. import android.content.Context;  
  9. import android.view.LayoutInflater;  
  10. import android.view.View;  
  11. import android.view.ViewGroup;  
  12. import android.widget.BaseAdapter;  
  13. import android.widget.Button;  
  14. import android.widget.CheckBox;  
  15. import android.widget.CompoundButton;  
  16. import android.widget.ImageView;  
  17. import android.widget.TextView;  
  18. import android.widget.CompoundButton.OnCheckedChangeListener;  
  19. /**  
  20.  * @author Himi  
  21.  *   
  22.  */ 
  23. public class MySimpleAdapter extends BaseAdapter {  
  24.     private LayoutInflater mInflater;  
  25.     private List<Map<String, Object>> list;  
  26.     private int layoutID;  
  27.     private String flag[];  
  28.     private int ItemIDs[];  
  29.     public MySimpleAdapter(Context context, List<Map<String, Object>> list,  
  30.             int layoutID, String flag[], int ItemIDs[]) {  
  31.         this.mInflater = LayoutInflater.from(context);  
  32.         this.list = list;  
  33.         this.layoutID = layoutID;  
  34.         this.flag = flag;  
  35.         this.ItemIDs = ItemIDs;  
  36.     }  
  37.     @Override 
  38.     public int getCount() {  
  39.         // TODO Auto-generated method stub  
  40.         return list.size();  
  41.     }  
  42.     @Override 
  43.     public Object getItem(int arg0) {  
  44.         // TODO Auto-generated method stub  
  45.         return 0;  
  46.     }  
  47.     @Override 
  48.     public long getItemId(int arg0) {  
  49.         // TODO Auto-generated method stub  
  50.         return 0;  
  51.     }  
  52.     @Override 
  53.     public View getView(int position, View convertView, ViewGroup parent) {  
  54.         convertView = mInflater.inflate(layoutID, null);  
  55.         for (int i = 0; i < flag.length; i++) {//备注1  
  56.             if (convertView.findViewById(ItemIDs[i]) instanceof ImageView) {  
  57.                 ImageView iv = (ImageView) convertView.findViewById(ItemIDs[i]);  
  58.                 iv.setBackgroundResource((Integer) list.get(position).get(  
  59.                         flag[i]));  
  60.             } else if (convertView.findViewById(ItemIDs[i]) instanceof TextView) {  
  61.                 TextView tv = (TextView) convertView.findViewById(ItemIDs[i]);  
  62.                 tv.setText((String) list.get(position).get(flag[i]));  
  63.             }else{  
  64.                 //...备注2  
  65.             }  
  66.         }  
  67.         addListener(convertView);  
  68.         return convertView;  
  69.     }  
  70. /**  
  71.  * 童鞋们只需要将需要设置监听事件的组件写在下面这方法里就可以啦!  
  72.  * 别的不需要修改!  
  73.  * 备注3  
  74.  */ 
  75.     public void addListener(View convertView) {  
  76.         ((Button)convertView.findViewById(R.id.btn)).setOnClickListener(  
  77.                 new View.OnClickListener() {  
  78.                     @Override 
  79.                     public void onClick(View v) {  
  80.                         new AlertDialog.Builder(MainActivity.ma)  
  81.                         .setTitle("自定义通用SimpleAdapter")  
  82.                         .setMessage("按钮成功触发监听事件!")  
  83.                         .show();  
  84.                     }  
  85.                 });  
  86.         ((CheckBox)convertView.findViewById(R.id.cb)).  
  87.         setOnCheckedChangeListener(new OnCheckedChangeListener() {  
  88.             @Override 
  89.             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {  
  90.                 new AlertDialog.Builder(MainActivity.ma)  
  91.                 .setTitle("自定义通用SimpleAdapter")  
  92.                 .setMessage("CheckBox成功触发状态改变监听事件!")  
  93.                 .show();  
  94.             }  
  95.         });  
  96.     }  
    备注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










本文转自 xiaominghimi 51CTO博客,原文链接:http://blog.51cto.com/xiaominghimi/606981,如需转载请自行联系原作者
目录
相关文章
|
1月前
|
Android开发 开发者
安卓应用开发中的自定义视图
【9月更文挑战第37天】在安卓开发的海洋中,自定义视图犹如一座座小岛,等待着勇敢的探索者去发现其独特之处。本文将带领你踏上这段旅程,从浅滩走向深海,逐步揭开自定义视图的神秘面纱。
38 3
|
1月前
|
数据可视化 Android开发 开发者
安卓应用开发中的自定义View组件
【10月更文挑战第5天】在安卓应用开发中,自定义View组件是提升用户交互体验的利器。本篇将深入探讨如何从零开始创建自定义View,包括设计理念、实现步骤以及性能优化技巧,帮助开发者打造流畅且富有创意的用户界面。
78 0
|
14天前
|
搜索推荐 前端开发 Android开发
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
|
16天前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
28 5
|
1月前
|
XML 前端开发 Java
安卓应用开发中的自定义View组件
【10月更文挑战第5天】自定义View是安卓应用开发的一块基石,它为开发者提供了无限的可能。通过掌握其原理和实现方法,可以创造出既美观又实用的用户界面。本文将引导你了解自定义View的创建过程,包括绘制技巧、事件处理以及性能优化等关键步骤。
|
2月前
|
Android开发 开发者
安卓开发中的自定义视图:从入门到精通
【9月更文挑战第19天】在安卓开发的广阔天地中,自定义视图是一块充满魔力的土地。它不仅仅是代码的堆砌,更是艺术与科技的完美结合。通过掌握自定义视图,开发者能够打破常规,创造出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战应用,一步步展示如何用代码绘出心中的蓝图。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往创意和效率的大门。让我们一起探索自定义视图的秘密,将你的应用打造成一件艺术品吧!
61 10
|
2月前
|
XML 编解码 Android开发
安卓开发中的自定义视图控件
【9月更文挑战第14天】在安卓开发中,自定义视图控件是一种高级技巧,它可以让开发者根据项目需求创建出独特的用户界面元素。本文将通过一个简单示例,引导你了解如何在安卓项目中实现自定义视图控件,包括创建自定义控件类、处理绘制逻辑以及响应用户交互。无论你是初学者还是有经验的开发者,这篇文章都会为你提供有价值的见解和技巧。
45 3
|
5天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
7天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
9天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
【10月更文挑战第35天】在数字化时代,安卓应用的开发成为了一个热门话题。本文旨在通过浅显易懂的语言,带领初学者了解安卓开发的基础知识,同时为有一定经验的开发者提供进阶技巧。我们将一起探讨如何从零开始构建第一个安卓应用,并逐步深入到性能优化和高级功能的实现。无论你是编程新手还是希望提升技能的开发者,这篇文章都将为你提供有价值的指导和灵感。