2012-06-25 3 views
15

Мне нужен getOnClickListener() для просмотров в Android. Таким образом, я могу назначить временный OnClickListener своим представлениям. Я хочу, чтобы использовать его как это:getOnClickListener() в Android-представлениях

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); 
     } 
    }); 
} 

Проблема заключается в том, что эта функция doen't существует. Я также не могу наследовать от View для создания этого метода, потому что все виды Views могут быть переданы назначениюTempListener. Есть ли другой способ использовать это?

Редактировать: сделала небольшую ошибку в моем коде.

+0

Я хочу, чтобы назначить временную OnClickListener к уже выходя из представления. У меня нет контроля, где назначается оригинальный OnClickListener. Поэтому я не могу его хранить. – user969039

ответ

24

Вы можете сделать это с ... REFLECTION. * барабан рулон *

Этот маршрут чреват опасностью.

Я не рекомендую его, так как внутренняя структура класса может измениться в любое время, но вот как вы можете это сделать в настоящее время до 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; 
} 
+0

Работал как очарование. –

1

использование

oldListener = new view.OnClickListener() { 

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

      v.setOnClickListener(oldListener); 
     } 
    }); 

вместо

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

getOnClickListener не какой-либо метод View или Button в Зе документации Текущий API: для получения более подробной информации

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

+0

Я допустил ошибку: 'oldListener = view.setOnClickListener(); // не существует' должен был быть 'oldListener = view.getOnClickListener(); // не существует' – user969039

+0

см. мой ответ answer.thanks –

0

Niet!

oldListener в ответах, приведенных в каждом случае, переопределяется, и это старое состояние или определение теряется независимо от его имени, притворяясь иначе.

Следуя этой технологии: Get current onClickListener of an Android View object «старый» слушатель должен быть установлен в методе OnClick абстрактного класса в и любой временной слушатель будет использовать setOnClickListener вместе с вызовом супер для того, чтобы (пере) установить старый слушатель когда или, если необходимо,

Код настройки температора темпа не должен знать, что такое «старый» слушатель, но все еще должна быть какая-то форма координации, чтобы автор этого или этих слушателей мог сделать их абстрактными и использовать onClick, чтобы, например, установить прослушиватель нажатий, чтобы следовать протоколу.

В исключительных случаях вы можете обойти защищенный или частный спецификатор onclicklistener Просмотр: 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 или любой поглотитель по этому вопросу, который использует instrospection подход, если, конечно, это на самом деле работает :)

:)

2

вы можете переопределить класс и объявить onClicklistener для вашего зрения и писать и присваиватель для onClickListener поля:

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; 
    } 
} 
Смежные вопросы