Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Have a disabled onClick?

I want to be able to respond to a click event on a disabled switch, is that possible?

I have a switch that is not enabled until the user fills in some information, so it looks like this:

enter image description here

I want to prompt the user to fill out the information if they click on the disabled switch with a dialog, like so:

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

            if (!userInfo.isFilled){
                new AlertDialog.Builder(MainActivity.this)
                        .setTitle("Fill out info first!")
                        .setMessage("You must first fill out info before turning on this featurel")
                        .setNeutralButton("Okay", null)
                        .show();
            }
        }
    });

However, the onClick() is not triggered when I click on the disabled switch, so how do I get when the user clicks on it?

like image 464
Ruchir Baronia Avatar asked Aug 07 '16 21:08

Ruchir Baronia


People also ask

How can I disable href If onclick is executed?

To disable href if onclick is executed with JavaScript, we call preventDefault to stop the default navigation action. document. getElementsById("ignore-click"). addEventListener("click", (event) => { event.

How do I turn off onclick event in react?

Use the disabled prop to disable a button in React, e.g. <button disabled={true}>Click</button> . You can use the prop to conditionally disable the button based on the value of an input field or another variable or to prevent multiple clicks to the button. Copied!


3 Answers

You could place a transparent View on top of the Switch and toggle its enabled state opposite the Switch, and show the message when this overlaid View is clicked.

like image 148
Karakuri Avatar answered Oct 19 '22 22:10

Karakuri


From the View.java source code,

public boolean dispatchTouchEvent(MotionEvent event) {
    // If the event should be handled by accessibility focus first.
    if (event.isTargetAccessibilityFocus()) {
        // We don't have focus or no virtual descendant has it, do not handle the event.
        if (!isAccessibilityFocusedViewOrHost()) {
            return false;
        }
        // We have focus and got the event, then use normal event dispatch.
        event.setTargetAccessibilityFocus(false);
    }

    boolean result = false;

    if (mInputEventConsistencyVerifier != null) {
        mInputEventConsistencyVerifier.onTouchEvent(event, 0);
    }

    final int actionMasked = event.getActionMasked();
    if (actionMasked == MotionEvent.ACTION_DOWN) {
        // Defensive cleanup for new gesture
        stopNestedScroll();
    }

    if (onFilterTouchEventForSecurity(event)) {
        //noinspection SimplifiableIfStatement
        ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnTouchListener != null
                && (mViewFlags & ENABLED_MASK) == ENABLED
                && li.mOnTouchListener.onTouch(this, event)) {
            result = true;
        }

        if (!result && onTouchEvent(event)) {
            result = true;
        }
    }

    if (!result && mInputEventConsistencyVerifier != null) {
        mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
    }

    // Clean up after nested scrolls if this is the end of a gesture;
    // also cancel it if we tried an ACTION_DOWN but we didn't want the rest
    // of the gesture.
    if (actionMasked == MotionEvent.ACTION_UP ||
            actionMasked == MotionEvent.ACTION_CANCEL ||
            (actionMasked == MotionEvent.ACTION_DOWN && !result)) {
        stopNestedScroll();
    }

    return result;
}

the enabled flag ensures the UnhandledEvents are consumed however not passed along to the listeners,thereby bypassing all your possible code.So it is not possible to listen to events on a disabled view.

That said, your options are,

  1. Change the style to mimic that of a disabled view as mentioned here,and then add your required functionality.
  2. Add a overlay invisible view to perform your required functionality which you can set to Gone once the view should be enabled.
  3. Use something apart from enabled,(you could setClickable(false) and consume touch events)
like image 10
Droidekas Avatar answered Oct 19 '22 20:10

Droidekas


You can set onTouchListener and react to boolean (e.g isToggleEnable) reference with respect to the user's previous actions:

 mySwitch.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(!isToggleEnable){
                //Taost here
                }
                //If isToggleEnable = false on return OnClickListener won't be called
                return isToggleEnable; 
            }
        });
like image 8
Nir Duan Avatar answered Oct 19 '22 20:10

Nir Duan