在做安卓应用开发的时候很经常会用到ListView,并且每一个Item里面都会有按钮之类的需要进行事件监听的控件。在给按钮添加OnClickListener的时候,一开始很下意识的会想在ListView的adapter的getView方法中找到每个Button并new一个OnClickListener分配给这个button。但是当数据量很大的时候,new出来这么多个监听器势必会对内存造成一定的压力,而且每个Listener的功能完全一样,Listener里面所需知道的,不过是调用者所在的Item的index而已。怎么样才能更好地利用内存呢?

既然每个Listener的功能一样,那么完全可以用单例模式构造一个Listener。如下:

 1 class MyOnClickListener implements OnClickListener {
2
3 private static MyOnClickListener instance = null;
4
5 private MyOnClickListener() {
6 }
7
8 public static MyOnClickListener getInstance() {
9 if (instance == null)
10 instance = new MyOnClickListener() ;
11 return instance;
12 }
13
14 @Override
15 public void onClick(View view) {
16 //TODO: do something here
17 }
18 }

而在getView方法中,获取到button实例之后,只需要通过button.setOnClickListener(MyOnClickListener.getInstance());对按钮设置监听器了。这样的话每一个按钮便必然用的是同一个Listener对象。

但是我们的需求并不止于此,很多时候,我们还需要知道具体是哪个position的button被点击了,我们需要根据position在Listener里面做出不一样的动作。

想要在Listener内部了解外部控件的属性,我们首先想到的是传参,但是由于我们的Listener使用的是单例模式,每个按钮往Listner里面传的参数必然会覆盖前一个按钮传的参数。于是我们的解决方案只剩下一种,那就是通过onClick函数的参数(View view)来获取该信息。然而,此处的view应该是一个Button,而Button是不具备position信息的。又于是,自然而然的,解决方案出来了:重载Button类。

 1 class MyButton extends Button {
2
3 private int index = -1;
4
5 public int getIndex() {
6 return index;
7 }
8
9 public void setIndex(int index) {
10 this.index = index;
11 }
12
13 public MyButton(Context context) {
14 super(context);
15 // TODO: do something here if you want
16 }
17
18 public MyButton(Context context, AttributeSet attrs) {
19 super(context, attrs);
20 // TODO: do something here if you want
21 }
22
23 public MyButton(Context context, AttributeSet attrs, int defStyle) {
24 super(context, attrs, defStyle);
25 // TODO: do something here if you want
26 }
27 }

接下来我们需要做的,就是在xml文件中,将item里面的Button的类型改成我们自定义的MyButton。即将<Button> </Button>改成<your.package.name.MyButton> </your.package.name.MyButton>,而在adapter的getView函数里面则把findViewById()获得的返回值强制转换成为MyButton,并调用其setIndex函数设置Index值。同时MyOnClickListener中重载的的onClick函数也一样将view对象转换成MyButton类型,并通过调用getIndex函数获取position信息,以做相应操作。

Adapter中:

 1 // ....
2 MyButton button = null;
3 // ....
4 @Override
5 public View getView(int position, View convertView, ViewGroup parentView) {
6 View view = convertView;
7 if (convertView == null) {
8 view = LayoutInflater.from(activity).inflate(R.layout.company_detail_campus_talk_item, null);
9 }
10
11 // ....
12
13 button = (MyButton) view.findViewById(R.id.YOUR_BUTTON_ID);
14 button.setIndex(position);
15 button.setOnClickListener(MyOnClickListener.getInstance());
16 }

MyOnClickListener中:

1 // ....
2
3 @Override
4 public void onClick(View view) {
5
6 int index = ((MyButton)view).getIndex();
7
8 // ....
9 }

这样,我们便实现了使用同一个Listener对ListView中不同Item的按钮进行事件监听处理的业务逻辑。如果需要在Adapter和Listener之间共享数据的话,可以通过增加Listener的getInstance函数的参数以及Listener类的成员变量实现。

Android ListView中按钮监听器设置的解决方案的更多相关文章

  1. ListView中button监听器 设置 及 优化

    在应用开发中常常会用到ListView,而且每个Item里面都会有button之类的须要进行事件监听的控件.在给button加入OnClickListener的时候,一開始非常下意识的会想在ListV ...

  2. [Android]ListView中分割线的设置

    1.在布局文件中ListView元素中通过属性设置 android:divider="#fffff"  分割线颜色 android:dividerHeight="1px& ...

  3. Android 关于ListView中按钮监听的优化问题(方法一)

    在Android应用开发过程中经常会用到ListView,并且每次在item中都要对点击事件进行监听.在给按钮添加OnClickListener时,一般会下意识的在getView()中找到每一个But ...

  4. android 自定义adapter和线程结合 + ListView中按钮滑动后状态丢失解决办法

    adapter+线程 1.很多时候自定义adapter的数据都是来源于服务器的,所以在获取服务器的时候就需要异步获取,这里就需要开线程了(线程池)去获取服务器的数据了.但这样有的时候adapter的中 ...

  5. Android 关于ListView中按钮监听的优化问题(方法二)

    关于ListView中按钮监听的优化问题(方法一)地址: http://www.cnblogs.com/steffen/p/3951901.html 之前的方法一,虽然能够解决position的传递, ...

  6. Android ListView的item背景色设置以及item点击无响应等相关问题

    Android ListView的item背景色设置以及item点击无响应等相关问题 在Android开发中,listview控件是非常常用的控件,在大多数情况下,大家都会改掉listview的ite ...

  7. android listview中item通过viewpager实现《IT蓝豹》

    android listview中item通过viewpager实现 android listview中item通过viewpager实现,每一个item都支持viewpager实现图片切换功能.本项 ...

  8. Android Listview中Button按钮点击事件冲突解决办法

    今天做项目时,ListView中含有了Button组件,心里一早就知道肯定会有冲突,因为以前就遇到过,并解决过,可惜当时没有记录下来. 今天在做的时候,继续被这个问题郁闷了一把,后来解决后,赶紧来记录 ...

  9. Android ListView中Item点击事件失效解决方案

    欢迎关注公众号,每天推送Android技术文章,二维码如下:(可扫描) 在平常的开发过程中,我们的ListView可能不只是简单的显示下文本或者按钮,更多的是显示复杂的布局,这样的话,我们就得自己写布 ...

随机推荐

  1. MySQL性能剖析工具(pt-query-digest)【转】

    这个工具同样来自percona-toolkit 该工具集合的其他工具 MySQL Slave异常关机的处理 (pt-slave-restart)  验证MySQL主从一致性(pt-table-chec ...

  2. [转]mitmproxy套件使用攻略及定制化开发

    mitmproxy是一款支持HTTP(S)的中间人代理工具.不同于Fiddler2,burpsuite等类似功能工具,mitmproxy可在终端下运行.mitmproxy使用Python开发,是辅助w ...

  3. Owin中间件动手做

    摘要:本文目的是了解Owin基本原理.讲述如何从控制台创建一个自宿主的OwinHost,然后再编写一两个中间件 准备工作 首先通过VisualStudio创建一个控制台应用 然后添加Owin的Nuge ...

  4. 09 Go 1.9 Release Notes

    Go 1.9 Release Notes Introduction to Go 1.9 Changes to the language Ports ppc64x requires POWER8 Fre ...

  5. shell升级

    对/sbin/nologin的理解   系统账号的shell使用 /sbin/nologin ,此时无法登陆系统,即使给了密码也不行.   所谓“无法登陆”指的仅是这个用户无法使用bash或其他she ...

  6. mysql innodb 行级锁升级

    创建数据表test,表定义如下所示: CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) NO ...

  7. PHP 字符串截取()[]{} 中内容

    $str="你好<我>(爱)[北京]{天安门}"; echo f1($str); //返回你好 echo f2($str); //返回我 echo f3($str); ...

  8. CAS5.2x单点登录(二)cas服务器连接数据库

    前面一节应该已经告诉大家如何搭建cas的服务器了,可是搭建好能用吗?我们现在的用户验证是在哪呢?哪个默认的用户名和密码有是在哪呢? 本节就讲一下如何使用cas服务器连接我们自己的用户数据库,毕竟没有哪 ...

  9. day11--RabbitMQ、Redis

        RabbitMQ:就是消息队列与Python里面的queue功能类似.线程和进程queue只能Python自己使用:不同机器和程序传递消息就要使用RabbitMQ了,中间传递. RabbitM ...

  10. date命令使用文档

    date命令的帮助信息 [root@localhost source]# date --help用法:date [选项]... [+格式] 或:date [-u|--utc|--universal] ...