关于android:禁用所有视图的touch事件

Disable the touch events for all the views

为所有视图禁用触摸事件的最佳方法是什么?


这是用于禁用某个视图组的所有子视图的功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 /**
   * Enables/Disables all child views in a view group.
   *
   * @param viewGroup the view group
   * @param enabled <wyn>true</wyn> to enable, <wyn>false</wyn> to disable
   * the views.
   */
  public static void enableDisableViewGroup(ViewGroup viewGroup, boolean enabled) {
    int childCount = viewGroup.getChildCount();
    for (int i = 0; i < childCount; i++) {
      View view = viewGroup.getChildAt(i);
      view.setEnabled(enabled);
      if (view instanceof ViewGroup) {
        enableDisableViewGroup((ViewGroup) view, enabled);
      }
    }
  }


重写活动的dispatchTouchEvent方法,如下所示:

1
2
3
4
@Override
public boolean dispatchTouchEvent(MotionEvent ev){      
  return true;//consume
}

如果返回true,则所有触摸事件均被禁用。

返回false以使其正常工作


您可以尝试:

1
your_view.setEnabled(false);

应禁用触摸事件。

或者您可以尝试(感谢Ercan):

1
2
3
4
@Override
public boolean dispatchTouchEvent(MotionEvent ev){      
  return true;//consume
}

1
2
3
4
5
6
7
8
9
public boolean dispatchTouchEvent(MotionEvent ev) {
    if(!onInterceptTouchEvent()){
        for(View child : children){
            if(child.dispatchTouchEvent(ev))
                return true;
        }
    }
    return super.dispatchTouchEvent(ev);
}


只要且仅当inProgress变量设置为false时,这段代码基本上会将此事件传播到父视图,从而允许触摸事件。

1
2
3
4
5
6
7
8
private boolean inProgress = false;

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (!inProgress)
        return super.dispatchTouchEvent(ev);
    return true;
 }


使用它。返回true表示侦听器已经消耗了该事件,而android无需执行任何操作。

1
2
3
4
5
6
view.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
});


如何在所有视图上覆盖透明视图并捕获所有触摸事件?


1
2
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                     WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

我做了这种方法,对我来说很完美。它禁用选定视图的所有触摸事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void disableView(View v) {

    v.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });

    if (v instanceof ViewGroup) {
        ViewGroup vg = (ViewGroup) v;
        for (int i = 0; i < vg.getChildCount(); i++) {
            View child = vg.getChildAt(i);
            disableView(child);
        }
    }
}

可能无法对整个应用程序进行处理。您将必须为每个视图覆盖onTouchEvent()并忽略用户输入。


在Kotlin:

1
2
3
4
5
6
7
8
9
10
fun View.setEnabledRecursively(enabled: Boolean) {
    isEnabled = enabled
    if (this is ViewGroup)
        (0 until childCount).map(::getChildAt).forEach { it.setEnabledRecursively(enabled) }
}

// usage
import setEnabledRecursively

myView.setEnabledRecursively(false)


最简单的方法是

1
2
3
4
private fun enableDisableActivty(isEnable : Boolean){
            if(!isEnable) window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
            else window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
    }

根据您的评论:

i just want to be able to disable the views of the current activity at some point

您似乎想禁用当前活动的所有触摸,而无论触摸的视图如何。

在适当的时间从覆盖Activity.dispatchTouchEvent(MotionEvent)返回true将消耗触摸并有效地完成此操作。此方法是触摸方法调用链中的第一个。


一种更简单的方法是通过布局(即.xml)文件禁用它:
只需添加

1
 android:shouldDisableView="True"

对于要禁用触摸事件的视图。