如何获得一个观点的听众

我编写与其他应用程序交互的服务。 它在已经有侦听器的视图(button,textview,…)上注册侦听器。 我需要用我自己的听众(作品)取代他们,做一些事情,然后注销我的听众,并恢复旧的。

  1. 带有onClickListener的button正在运行
  2. 我的服务在UI-Thread +内部注册了一个onClickListener
  3. 我的服务恢复了旧的监听器

如果有一个view.getOnClickListener方法,将会很容易。 然后,我可以保存旧的,当我完成时,replace新的听众。

有什么办法从一个视图获取侦听器或有更多的一个相同types的侦听器绑定到一个视图?

 Button btn = (Button) findViewById(R.id.btn1); btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { //do something } }); // I need to do, but found no solution for that. View.OnClickListener oldListener = btn.getOnClickListener(); 

如果我将新的听众注册到一个视图,那么旧的video会被覆盖,对吧? 如果两个听众(“新”和“旧”)同时存在也是可以的。 只有旧的一定不能消失。

编辑:不幸的是我没有可能保存监听器的任务。 我需要从视图组件后退。

谢谢

Solutions Collecting From Web of "如何获得一个观点的听众"

感谢mihail的提示(感谢:))与隐藏的API ,我已经find一个解决scheme,让分配后的监听器:

android.view.View类有一个嵌套的类static class ListenerInfo ,它将所有侦听static class ListenerInfo存储在View(API 14+)上。 在较旧的版本中,侦听器是android.view.View中的私有字段。

该字段可以通过reflection访问。 就我而言(API 14+),

 // get the nested class `android.view.View$ListenerInfo` Field listenerInfoField = null; listenerInfoField = Class.forName("android.view.View").getDeclaredField("mListenerInfo"); if (listenerInfoField != null) { listenerInfoField.setAccessible(true); } Object myLiObject = null; myLiObject = listenerInfoField.get(myViewObj); // get the field mOnClickListener, that holds the listener and cast it to a listener Field listenerField = null; listenerField = Class.forName("android.view.View$ListenerInfo").getDeclaredField("mOnClickListener") if (listenerField != null && myLiObject != null) { View.OnClickListener myListener = (View.OnClickListener) listenerField.get(myLiObject); } 

在这段代码之后(我错过了很多的try-catch-blocks),myListener对象保存着onClickListener的实例,这个实例已经匿名声明给视图了。 它也适用于任何其他侦听器,只需将“mOnClickListener参数”replace为您在reflection中需要的参数,然后正确转换即可。

请注意,即将发布的版本中的代码更改可能会导致无法正常工作。

在这里find最终的教程: http : //andwise.net/?p=161

创build实现OnClickListener

 public static class MyClickListener1 implements OnClickListener{ Activity mActivity; MyClickListener1(Acivity activity){ mActivity=activity; } @Override public void onClick(View v) { //do something } } public static class MyClickListener2 implements OnClickListener{ @Override public void onClick(View v) { //do something } } 

并在你的代码中,你可以很容易地使用它们:

 btn.setOnClickListener(new MyClickListener1(this)); btn.setOnClickListener(new MyClickListener2()); 

或者你可以创build实例并重用它们:

 OnClickListener listener1 = new MyClickListener1(this); OnClickListener listener2 = new MyClickListener2(); btn.setOnClickListener(listener1); btn.setOnClickListener(listener2); 

你也可以定义一个构造函数来传递这些类中所需的任何东西。 我通常像MyClickListener1那样传递活动

编辑:如果你想让听众像button中的对象,你可以使用标签。

 btn.setTag(listener1); btn.setOnClickListener(listener1); 

然后才能使用它

 OnClickListener old_listener = (OnClickListenr)btn.getTag(); 

创build两个OnCLickListener实例,并分配第一个或第二个button:

  Button b = (Button) findViewById(R.id.Button1); OnClickListener listener_new = new OnClickListener() { @Override public void onClick(View v) { Log.d("APP", "NEW CLICK LISTENER ACTIVE"); } }; OnClickListener listener_old = new OnClickListener() { @Override public void onClick(View v) { Log.d("APP", "OLD CLICK LISTENER ACTIVE"); } }; //setting listener b.setOnClickListener(listener_old); b.callOnClick(); //changing listener b.setOnClickListener(listener_new); b.callOnClick(); //return your old listener! b.setOnClickListener(listener_old); b.callOnClick(); 

添加:

OnClickListener是inheritance自View类的Button类的受保护字段。 “mOnClickListener”字段的名称。 即使通过反思,我也无法得到它。

 void getListener(Button b) { java.lang.reflect.Field field = getClass().getSuperclass().getSuperclass().getDeclaredField("mOnClickListener"); } 

所以,如果您无法访问创build的代码,则无法获取Button的现有侦听器。

但是,如果您有权访问Activity的对象(并且我们知道您已经设置了新的侦听器button),那么您可以在侦听器上添加您的button。 使现有的button不可见。 并在必要时进行回滚。