2012-06-25 31 views
15

Tôi cần getOnClickListener() cho Chế độ xem trong Android. Bằng cách này tôi có thể gán một OnClickListener tạm thời cho Views của tôi. Tôi muốn sử dụng nó như thế này:getOnClickListener() trong chế độ xem 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); 
     } 
    }); 
} 

Vấn đề là chức năng này doen't tồn tại. Tôi cũng không thể kế thừa từ View để tạo phương thức này, bởi vì tất cả các loại Views đều có thể được chuyển tới assignTempListener. Có cách nào khác để sử dụng điều này không?

Chỉnh sửa: đã tạo một lỗi nhỏ trong mã của tôi.

+0

Tôi muốn gán một OnClickListener tạm thời để một đã thoát Xem. Tôi không có quyền kiểm soát nơi ban đầu OnClickListener được chỉ định. Vì vậy, tôi không thể lưu trữ nó ở đó. – user969039

Trả lời

24

Bạn có thể làm điều này với ... REFLECTION. * cuộn trống *

Tuyến đường này đầy nguy hiểm.

Tôi không khuyên bạn nên vì cấu trúc bên trong của lớp học có thể thay đổi bất kỳ lúc nào, nhưng dưới đây là cách bạn có thể thực hiện nó hiện tại lên Android 4.2.2 nếu nó thực sự không thể tránh khỏi:

/** 
* 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

Làm việc như một nét duyên dáng. –

1

sử dụng

oldListener = new view.OnClickListener() { 

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

      v.setOnClickListener(oldListener); 
     } 
    }); 

thay vì

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

getOnClickListener không phải là bất kỳ phương pháp cho View hoặc cho Button trong tài liệu see Current API để biết thêm chi tiết

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

+0

Tôi đã thực hiện một sai lầm: 'oldListener = view.setOnClickListener(); // không exist' phải được 'oldListener = view.getOnClickListener(); // không exist' – user969039

+0

thấy chỉnh sửa của tôi answer.thanks –

0

Niet!

OldListener trong câu trả lời được đưa ra là trong mỗi trường hợp được xác định lại và trạng thái cũ hoặc định nghĩa bị mất bất kể tên giả vờ khác.

Tiếp theo kỹ thuật này: Get current onClickListener of an Android View object người nghe 'cũ' sẽ được thiết lập trong phương pháp onClick lớp trừu tượng của và bất kỳ người nghe tạm thời sẽ sử dụng setOnClickListener cùng với một cuộc gọi đến siêu để (lại) đặt người nghe cũ khi hoặc khi thích hợp

Mã cài đặt trình nghe tạm thời không cần biết người nghe 'cũ' là gì Tuy nhiên vẫn cần có một số hình thức phối hợp để tác giả hoặc người nghe đó làm cho họ trừu tượng và sử dụng phương pháp onClick để đặt trình nghe nhấp chuột trên, trong ngắn hạn, để thực hiện theo một giao thức.

Đặc biệt bạn có thể muốn bỏ qua các vòng loại protected hay private của Xem thành viên OnClickListener: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/view/View.java#View.0mOnClickListener và sau đó làm một chút http://www.jguru.com/faq/view.jsp?EID=321191 đó sẽ giúp bạn có được người nghe.

Bạn thậm chí có thể muốn viết getOnClickListener riêng của bạn, hoặc bất kỳ getter cho rằng vấn đề, mà sử dụng cách tiếp cận instrospection, nếu tất nhiên nó thực sự hoạt động :)

:)

2

bạn có thể ghi đè lên lớp và tuyên bố một OnClickListener cho tầm nhìn của bạn và viết setter và getter cho OnClickListener lĩnh vực:

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; 
    } 
} 
Các vấn đề liên quan