Android视图中的getOnClickListener()

guicsvcw  于 2023-06-04  发布在  Android
关注(0)|答案(6)|浏览(196)

我需要一个getOnClickListener()在Android的视图。这样我就可以为我的视图分配一个临时的OnClickListener。我想这样使用它:

private View.OnClickListener oldListener;

public void assignTempListener(View view) {
    oldListener = view.getOnClickListener(); // doesn't exist

    view.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // some code

            v.setOnClickListener(oldListener);
        }
    });
}

问题是这个函数不存在。我也不能从View继承来创建这个方法,因为所有类型的View都可以传递给assignTempListener。还有别的办法吗
编辑:在我的代码中犯了一个小错误。

kgsdhlau

kgsdhlau1#

您可以使用...反射来执行此操作。* 鼓声响起 *
这条路充满了危险。
我不推荐这样做,因为类的内部结构随时都可能发生变化,但如果真的不可避免,您可以在Android 4.2.2中执行以下操作:

/**
 * Returns the current View.OnClickListener for the given View
 * @param view the View whose click listener to retrieve
 * @return the View.OnClickListener attached to the view; null if it could not be retrieved
 */
public View.OnClickListener getOnClickListener(View view) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        return getOnClickListenerV14(view);
    } else {
        return getOnClickListenerV(view);
    }
}

//Used for APIs lower than ICS (API 14)
private View.OnClickListener getOnClickListenerV(View view) {
    View.OnClickListener retrievedListener = null;
    String viewStr = "android.view.View";
    Field field;

    try {
        field = Class.forName(viewStr).getDeclaredField("mOnClickListener");
        retrievedListener = (View.OnClickListener) field.get(view);
    } catch (NoSuchFieldException ex) {
        Log.e("Reflection", "No Such Field.");
    } catch (IllegalAccessException ex) {
        Log.e("Reflection", "Illegal Access.");
    } catch (ClassNotFoundException ex) {
        Log.e("Reflection", "Class Not Found.");
    }

    return retrievedListener;
}

//Used for new ListenerInfo class structure used beginning with API 14 (ICS)
private View.OnClickListener getOnClickListenerV14(View view) {
    View.OnClickListener retrievedListener = null;
    String viewStr = "android.view.View";
    String lInfoStr = "android.view.View$ListenerInfo";

    try {
        Field listenerField = Class.forName(viewStr).getDeclaredField("mListenerInfo");
        Object listenerInfo = null;

        if (listenerField != null) {
            listenerField.setAccessible(true);
            listenerInfo = listenerField.get(view);
        }

        Field clickListenerField = Class.forName(lInfoStr).getDeclaredField("mOnClickListener");

        if (clickListenerField != null && listenerInfo != null) {
            retrievedListener = (View.OnClickListener) clickListenerField.get(listenerInfo);
        }
    } catch (NoSuchFieldException ex) {
        Log.e("Reflection", "No Such Field.");
    } catch (IllegalAccessException ex) {
        Log.e("Reflection", "Illegal Access.");
    } catch (ClassNotFoundException ex) {
        Log.e("Reflection", "Class Not Found.");
    }

    return retrievedListener;
}
czfnxgou

czfnxgou2#

你可以覆盖这个类,为你的视图声明一个onClicklistener,并为onClickListener字段写setter和getter:

public class SAutoBgButton extends ImageButton {

  public View.OnClickListener mOnClickListener;

  @Override
  public void setOnClickListener(OnClickListener l) {
    super.setOnClickListener(l);
    mOnClickListener = l;
  }
  public OnClickListener getmOnClickListener() {
    return mOnClickListener;
  }
}
li9yvcax

li9yvcax3#

答案可以很简单

OnClickListener ocl = new OnClickListener { 
    @Override
    public void onClick(View view) {
        clickableView.performClick();
    }
}

onclicklistener的全部功能,除了一件事--你不能把任何视图作为参数传递给它,clickableView将是处理程序,但在大多数情况下它是足够的。

4bbkushb

4bbkushb4#

使用

oldListener = new view.OnClickListener() {

        @Override
        public void onClick(View v) {
            // some code

          v.setOnClickListener(oldListener);
        }
    });

而不是

oldListener = view.getOnClickListener(); // doesn't exist

getOnClickListener不是当前API中ViewButton的方法,详见文档

http://developer.android.com/reference/android/view/View.OnClickListener.html

zzzyeukh

zzzyeukh5#

不!
在给出的答案中,oldListener在每种情况下都被重新定义,并且它的旧状态或定义丢失,而不管它的名称是否以其他方式命名。
遵循此技术:Get current onClickListener of an Android View object 'old'侦听器将在抽象类的onClick方法中设置,并且任何临时侦听器都将使用setOnClickListener沿着对super的调用,以便在适当时(重新)设置旧侦听器
临时监听器设置代码不需要知道“旧”监听器是什么,但是仍然需要某种形式的协调,以便那个或那些监听器的作者使它们抽象,并使用onClick方法来设置点击监听器,简而言之,遵循协议。
在特殊情况下,您可能希望绕过onclicklistener视图成员的protected或private限定符:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/view/View.java#View.0mOnClickListener,然后执行一个小http://www.jguru.com/faq/view.jsp?EID=321191,这将使您获得侦听器。
你甚至可能想写你自己的getOnClickListener,或者任何使用inspection方法的getter,当然,如果它确实有效的话:)
:)

4dbbbstv

4dbbbstv6#

你可能需要View.hasOnClickListeners()返回true或false。

相关问题