2011-01-06 65 views
4

我有一個可點擊的自定義TextView。它定義了自己的onClick處理程序,以便根據點擊更改其外觀。但是,如果我然後在我的活動中定義第二個onClick處理程序,以便基於點擊按鈕執行某些操作,則只會調用一個onClick函數。 onClick是一個無效函數 - 有什麼方法可以說我沒有處理這個點擊,請將它傳遞給其他onClick處理程序?Android - 兩個onClick聽衆和一個按鈕

更清楚這裏是代碼:

內MyCheckButton延伸的TextView我:

setOnClickListener(mClickListener); 

    private OnClickListener mClickListener = new OnClickListener() { 
     public void onClick(View v) { 
      toggle(); 
     } 
    }; 

但是我包括MyCheckButton到我的活動,當然我需要的時候做一些它點擊所以我將另一個OnClickListener它:

MyCheckButton button= (MyCheckButtonButton) findViewById(R.id.cb); 
button.setOnClickListener(new OnClickListener(){ 
    @Override 
    public void onClick(View v) { 
     // do something in the app 
    } 

}); 

通過調用setOnClickListener兩次看來,我取代了原來的偵聽器,TOG從不調用改變外觀的gle()。如果已經使用onClick處理程序更改其外觀,那麼在單擊此按鈕時如何在我的活動中執行某些操作?我想我只會看到兩個OnClickListeners被調用。

+0

是的我認爲你是對的,你也可以嘗試在你的xml文件中給它一個onClick屬性,並在設置onClickListener之後查看它是否仍然會調用你的方法。 – schwiz 2011-01-06 20:39:51

+0

我猜這不是一個事件冒泡問題,我的問題是你不能將兩個OnClickListeners添加到相同的視圖?這是其他地方的標準做法,所以我很困惑。 – Mark 2011-01-06 20:41:23

+0

如果我使用xml onClick,setOnClickListener將覆蓋它。 – Mark 2011-01-06 20:49:27

回答

4

這是一個有點髒,但方式,如果你我會做這個需要多個聽衆的是註冊一個知道另一個的人。第一個(實際註冊的)根據事件的條件需要知道何時委派給其他聽衆。實際上,實際上並不需要有兩個類。第二類可以實現你想要的任何接口。另外,不需要爲你需要的創建一個特殊的界面。

public class MyClickListener implements OnClickListener{ 
    private SomeCustomClass mSecondListener = new SomeCustomClass(); 
    public void onClick(View v){ 
    if (needToForward){ 
     mSecondListener.handleClick(v); 
    }else{ 
     //handle the click 
    } 
    } 
} 

然後,在你爲你的活動代碼,你可以這樣做

MyClickListener lstn = new MyClickListener(); 
mCheckBox.setOnClickListener(lstn); 

是否有一個原因,這不會爲你工作?

或者,如果你想要,第二類也可以實現接口OnClickListener

此外,如果您需要真正冒泡,您可以定義自己的接口,支持將多個點擊偵聽器添加到恰好實現接口的中間類。從那裏,在該類的onClick()方法中,您將遍歷註冊的偵聽器,調用適當的方法。

-1

您可以通過以下方式附上一個onclick監聽器按鈕:

Button button= (Button) findViewById(R.id.button1); 
    button.setOnClickListener(new OnClickListener(){ 
     @Override 
     public void onClick(View v) { 
      // do something 
     } 

    }); 

相若方式,你的TextView應該有它在的OnClick聽衆。

+0

我的問題是兩個OnClickListeners和一個'按鈕',其中我的按鈕是我擴展的TextView。 – Mark 2011-01-06 20:39:03

1

因爲看起來我每個View只能有一個onClickListener。我想,我需要做的就是定義一個接口:

public interface MyOnClickListener { 
    public void onMyClick(View v); 
} 

從我的活動實現它,並覆蓋onMyClick功能做我想做的事情,並在MyCheckButton類我需要傳遞一個MyOnClickListener在構造保存並在onClick處理程序中調用listener.onMyClick。

讓我知道是否有更好的方法。我考慮在活動或MyCheckButton類中使用onTouch處理程序,但後來如果我將onTouch或onClick添加到任何一個,我將很難發現錯誤。

我的想法行不通,因爲我不知道如何從我的構造函數活動的引用:

public class TVCheckButton extends TextView { 

    private MyOnClickListener mListener; 

    public TVCheckButton(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     mListener = ???; 
    } 
} 
1

由於只有一個OnclickListener可以在Android 2.1上工作[我不知道更高版本的版本),使視圖保持私密和靜態,並創建一個靜態函數來改變它。

公共類爲ExampleActivity延伸活動{

private SomeOtherclass someOtherClass; 
private static Button b_replay; 

public void onCreate(Bundle savedInstanceState){ 
    someOtherClass = new SomeOtherclass(); 

    b_replay = (Button) findViewById(R.id.b_replay); 
    b_replay.setOnClickListener(someOtherClass); 
} 

public static void changeReplayText(String text){ 
    b_replay.setText(text); 
} 

}

2

更清潔的方法是使用CompositeListener模式。

來自 how can I set up multiple listeners for one event?

你不得不在你的項目中添加這個類:

/** 
* Aux class to collect multiple click listeners. 
*/ 
class CompositeListener implements OnClickListener { 
    private List<OnClickListener> registeredListeners = new ArrayList<OnClickListener>(); 

    public void registerListener (OnClickListener listener) { 
     registeredListeners.add(listener); 
    } 

    @Override 
    public void onClick(View v) { 

     for(OnClickListener listener:registeredListeners) { 
      listener.onClick(View v); 
     } 
    } 
} 

然後在您的MyCheckButton

private CompositeListener clickListener = new CompositeListener(); 

public MyCheckButton() 
{ 
    super.setOnClickListener(clickListener); //multi event listener initialization 
} 

@Override 
public void setOnClickListener(OnClickListener l) { 
    clickListener.registerListener(l); 
} 

無論您的通話內容添加到setOnClickListener會經歷這個覆蓋,被添加到列表中,並在事件被觸發時被調用。希望能幫助到你。

0

由於某種原因,我無法使用上面的答案,所以這裏是一個替代方案: //我在一個方法中擁有所有這一切,我有兩個按鈕,並且基於外部因素,一個可見,另一個不可見又名'走了'。所以,我已經檢查出來了!希望它可以幫助別人!

Button b = (Button) findViewById(R.id.b_reset); 
Button breakk = (Button) findViewById(R.id.b_break); 

    if ((findViewById(R.id.b_reset)).getVisibility() == View.VISIBLE) { 
     b.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

//一些代碼和方法...

  } 
     }); 
    } else if ((findViewById(R.id.b_break)).getVisibility() == View.VISIBLE) { 

     breakk.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

//一些代碼和方法...

  } 
     }); 
    } 
0

在第一類中,定義虛擬按鈕:

private static Button myVirtualButton = new Button(context); 

...和一個公開的方法來註冊它:

public static void registerMyVirtualButton(Button b) { myVirtualButton = b;} 

OnClickListener做任何動作是期望的,並且在最後,softclick虛擬按鈕:

if (myVirtualButton!=null) { myVirtualButton.callOnClick(); } 

在第二類中,定義一個按鈕及其OnClickListener與任何動作是另外期望。

通過registerMyVirtualButton將按鈕發送到第一類。 單擊第一個類的對象後,這兩個動作都會被執行。