onClick有禁用吗?

Ruc*_*nia 20 java string android button disabled-control

我希望能够在禁用的交换机上响应点击事件,这可能吗?

我有一个开关,直到用户填写一些信息才启用,所以它看起来像这样:

在此输入图像描述

我想提示用户填写信息,如果他们点击禁用的开关并带有对话框,如下所示:

 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();
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

但是,onClick()单击禁用的开关时不会触发,所以当用户点击它时如何获得?

Kar*_*uri 13

您可以在屏幕View顶部放置一个透明Switch屏幕,并在Switch对面切换其启用状态,并在View单击此重叠时显示消息.


Dro*_*kas 9

View.java源代码,

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;
}
Run Code Online (Sandbox Code Playgroud)

enabled标志确保消耗UnhandledEvents但不传递给侦听器,从而绕过所有可能的代码.因此无法在禁用的视图上侦听事件.

那就是说,你的选择是,

  1. 更改样式以模拟此处提到的禁用视图的样式,然后添加所需的功能.
  2. 添加叠加不可见视图以执行所需的功能,您可以在启用视图后将其设置为Gone.
  3. 使用除启用之外的东西,(你可以setClickable(false)和消费触摸事件)


Nir*_*uan 8

您可以根据用户之前的操作设置onTouchListener和响应boolean(例如isToggleEnable)引用:

 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; 
            }
        });
Run Code Online (Sandbox Code Playgroud)


TWL*_*TWL 5

当它被禁用时setEnabled(false),这些监听器将无法工作.

试试这种方式:不要禁用它,使用setOnCheckedChangeListener并检查你的is-entry-filled:

使用 setOnCheckedChangeListener

    switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (!isEntryFilled) {
                buttonView.setChecked(false);
                // your alert dialog
            } else {
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

这将重新检查它并关闭并弹出警报,直到isEntryFilled满足为止.

编辑

或者代替setEnabled(false),使用setClickable(false)或者android:clickable="false"因为文档说setClickable()点击事件有关.

而不是OnClickListener,尝试OnTouchListener.它将注册你的触摸式按键(并忽略你的触摸式按键),因为点击包含向下+向上.

    switch.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (!isEntryFilled) {
                buttonView.setChecked(false);
                // your alert dialog
            }
            return false;
        }
    });
Run Code Online (Sandbox Code Playgroud)

然后在其他地方,你检查isEntryFilled,重新激活你的开关switch.setClickable(true)


Com*_*Guy 5

尝试设置setFocusable(false)setEnabled(true)打开开关.这样,当交换机仍处于"禁用"状态时,将触发点击事件.取自这个答案.