[Android]在Adapter的getView方法中绑定OnClickListener比较好的方法

简介: 以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4146512.html    给ListView中每个item绑定点击事件的方法,比较常见的如下这种方式: 1 public View getView...

以下内容为原创,欢迎转载,转载请注明

来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4146512.html 

 

给ListView中每个item绑定点击事件的方法,比较常见的如下这种方式:

 1 public View getView(int positon, View convertView, ViewGroup parent){
 2     if(null == convertView){
 3         convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
 4     }
 5 
 6     Button button = ABViewUtil.obtainView(convertView, R.id.item_btn);
 7     button.setOnClickListener(new View.OnClickListener(){
 8         @Override
 9         public void onClick(View v){
10             Toast.makeText(context, "position: " + position, Toast.LENGTH_SHORT).show();
11         }
12     });
13 
14 }

然后运行,当然没问题。

但是这里有一个可以优化的地方,注意代码第7行,每次调用getView方法都会设置Button的OnClickListener,会生成很多不必要的OnClickListener对象。

所以,我们可以想到,在生成convertView时,同时设置Button的OnClickListener,convertView是被不断地复用的,这样的OnClickListener也就可以被不断地服用,也就是说在第3行和第4行之间进行这一步。这样,代码演化到如下:

 1 public View getView(int positon, View convertView, ViewGroup parent){
 2     if(null == convertView){
 3         convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
 4         Button button = ABViewUtil.obtainView(convertView, R.id.item_btn);
 5         button.setOnClickListener(new View.OnClickListener(){
 6             @Override
 7             public void onClick(View v){
 8                 Toast.makeText(context, "position: " + position, Toast.LENGTH_SHORT).show();
 9             }
10         });
11     }
12 }

这个代码看上去没什么问题,但是问题就在onClick回调的的第8行中使用的position的时候,因为这里使用的是匿名内部类(这个匿名内部类实现了View.OnClickListener这个接口),所以如果需要在onClick中使用position这个变量的话,需要把position声明为final。一旦声明了final,等到编译之后,这个position就会被作为这个匿名内部类中的一个private的成员变量。这样,ListView往下滚动,下面需要显示的item会重用上面不显示的convertView,convertView中的Button设置的OnClickListener实现类的对象,回调onClick时,使用的position其实是该OnClickListener实现类的成员变量position(这个position的值只是在构造的时候被初始化了而已!)。所以,这个ListView刚加载完数据后,还未滚动时,点击屏幕上的item都是正常的,但是如果一旦滚动,有view被重用了,这个时候,position的值就错乱了,所以在onClick中通过position获取到的item的数据当然也是错乱的了。

所以,要解决这个问题,就需要让onClick方法回调的时候得到的position是个正确的值,我们可以选择使用把当前显示的convertView对应的position值保存在convertView中,然后把这个convertView对象传入OnClickListener中保存,所以代码演化到如下:

 1 public View getView(int positon, View convertView, ViewGroup parent){
 2     if(null == convertView){
 3         convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
 4         Button button = ABViewUtil.obtainView(convertView, R.id.item_btn);
 5         button.setOnClickListener(new OnConvertViewClickListener(convertView, R.id.ab__id_adapter_item_position){
 6                 @Override
 7                 public void onClickCallBack(View registedView, int... positionIds){
 8                     Toast.makeText(context, "position: " + positionIds[0], Toast.LENGTH_SHORT).show();
 9                 }
10         });
11     }
12     convertView.setTag(R.id.ab__id_adapter_item_position, position);
13 }

就像上面第5行这样,Button绑定的是OnConvertViewClickListener,它是OnClickListener的一个实现类可以保存convertView到Listener中,到时候回调onClick方法的时候可以从保存的convertView中获取到当前显示的item的position(这个position是以tag的方式保存在convertView中的)。

当然,还需要做第12行这一步,它的目的是把当前显示的position保存到convertView中,提供给OnConvertViewClickListener获取当前的position。

这样就ok了,可以在onClickCallBack()方法中进行点击事件的处理了,每个button永远只有一个onClickListener。

注:使用OnConvertViewClickListener可以依赖AndroidBucket(https://github.com/wangjiegulu/AndroidBucket)项目

相关文章
|
12月前
|
XML 数据格式
Android_点击事件(实现接口OnClickListener)
关于每个Fragment里面都会有点击事件,如果一个Fragment里面很多控件有点击事件,那么就让这个Fragment类实现点击事件接口,例如
100 0
|
Android开发 C语言 数据格式
【android乱七八糟】关于OnClickListener事件中加switch语句讨论
  是这样的,我从A这个activity中转到B这个activity中同时根据A中的点击事件传递一个相应参数key过去。   在B这个activity中取出key值。
879 0
|
11小时前
|
存储 安全 Android开发
安卓应用开发:构建一个高效的用户登录系统
【5月更文挑战第3天】在移动应用开发中,用户登录系统的设计与实现是至关重要的一环。对于安卓平台而言,一个高效、安全且用户体验友好的登录系统能够显著提升应用的用户留存率和市场竞争力。本文将探讨在安卓平台上实现用户登录系统的最佳实践,包括对最新身份验证技术的应用、安全性考量以及性能优化策略。
|
11小时前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
|
11小时前
|
监控 Java Android开发
安卓应用开发:打造高效用户界面的五大策略
【4月更文挑战第29天】 在安卓应用开发的世界中,构建一个既美观又高效的用户界面(UI)对于吸引和保留用户至关重要。本文将深入探讨五种策略,这些策略可以帮助开发者优化安卓应用的UI性能。我们将从布局优化讲起,逐步过渡到绘制优化、内存管理、异步处理以及最终的用户交互细节调整。通过这些实践技巧,你将能够为用户提供流畅而直观的体验,确保你的应用在竞争激烈的市场中脱颖而出。
|
11小时前
|
存储 缓存 Java
安卓应用开发中的内存优化策略
【5月更文挑战第14天】在移动应用的开发过程中,尤其是对于资源受限的安卓平台,内存管理与优化是提升性能和用户体验的关键。本文将探讨针对安卓应用开发的内存优化技巧,包括避免内存泄漏、合理使用数据结构和算法、以及利用安卓系统的垃圾回收机制。通过这些方法,开发人员可以有效减少应用对系统资源的占用,从而延长电池寿命并提高应用的稳定性。
|
11小时前
|
Java Android开发
Android开发--Intent-filter属性详解
Android开发--Intent-filter属性详解
10 0
|
11小时前
|
物联网 Java 开发工具
安卓应用开发:打造未来移动生活
【5月更文挑战第10天】 随着科技的飞速发展,智能手机已成为我们日常生活中不可或缺的一部分。作为智能手机市场的两大巨头,安卓和iOS分别占据了一定的市场份额。在这篇文章中,我们将重点关注安卓应用开发,探讨如何利用先进的技术和创新思维,为用户打造更加便捷、智能的移动生活。文章将涵盖安卓应用开发的基本概念、关键技术、以及未来发展趋势等方面的内容。