简体   繁体   中英

OnClickListener doesn't work implicitly. Why?

I created custom button class that implements listener interface:

public class BlinkButton  extends Button implements View.OnClickListener {

List<OnClickListener> onClickListenerList = new ArrayList<OnClickListener>();

public BlinkButton(Context context) {
    super(context);
    this.setListener(new HighLightButtonListener());
}

//other constructors here 

public void setListener(OnClickListener listener){
    onClickListenerList.add(listener);
}

@Override
public void onClick(View v) {
    for(OnClickListener listener : onClickListenerList){
        listener.onClick(this);
    }
}

And I have view:

   <com.example.element.BlinkButton
    .../>

I claim onClick method inside com.example.element.BlinkButton should call implicitly when user clicks BlinkButton, but it's not. I have to write it explicitly: android:onClick="fireEvent" and

    public void fireEvent(View view) {
        fireEventButton.onClick(view);
    }  

Why BlinkButton.onClick(); doesn't trigger automatically once user clicks button?

Button (or its superclasses) don't have an onClick() method by itself. The one you implement comes from the View.OnClickListener interface your Button class implements.

You never set your class' OnClickListener , and from your code it seems you want the OnClickListener to be the class itself, so your custom Listeners are actually called.

Add this line to the constructor:

setOnClickListener(this);

So it looks like this:

public BlinkButton(Context context) {
    super(context);
    setOnClickListener(this);
    this.setListener(new HighLightButtonListener());
}

You'll also have to remove the onClick xml attribute.

BlinkButton class is only implementing the listener. If you look how View class handles clicks you'll find the following implementation:

public void setOnClickListener(OnClickListener l) {
    if (!isClickable()) {
        setClickable(true);
    }
    getListenerInfo().mOnClickListener = l;
}

Basically there is no way to override a method and get the click events. You can set a listener from your class that will be called on click and that will further send the event to all listeners from your list.

public class BlinkButton extends Button implements View.OnClickListener {

    List<OnClickListener> onClickListenerList = new ArrayList<OnClickListener>();

    public BlinkButton(Context context) {
        super(context);
        this.setListener(new HighLightButtonListener());
        this.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                for (OnClickListener listener : onClickListenerList) {
                    listener.onClick(this);
                }
            }
        };
    }

    //other constructors here 

    public void setListener(OnClickListener listener) {
        onClickListenerList.add(listener);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM