禁用所有视图的触摸事件

Posted

技术标签:

【中文标题】禁用所有视图的触摸事件【英文标题】:Disable the touch events for all the views 【发布时间】:2011-07-22 01:40:09 【问题描述】:

的最佳方法是什么?

【问题讨论】:

抱歉,这次改动的目的是什么?您可以创建一个递归过程来更改每个视图的 onTouchEvent() setEnabled(false);在你的 root_layout 您希望用户只使用按钮吗?在安卓设备上? ;) @T0X1C:这正是我想要的。但它不起作用。 @yosh:我不想永远禁用它们。我只是希望能够在某个时候禁用当前活动的视图。 【参考方案1】:

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

 /**
   * Enables/Disables all child views in a view group.
   * 
   * @param viewGroup the view group
   * @param enabled <code>true</code> to enable, <code>false</code> 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);
      
    
  

【讨论】:

@peceps 不幸的是它不适用于片段。例如,如果ViewGroup 有一个片段子级,添加到FragmentTransaction 中,则fragment 并且其子级不会被禁用。 @AlexAndro:我仍然使用通过FrameLayout 添加的Fragment 的方法,效果很好。 此解决方案假定视图组中的所有视图都是视图组的直接子级。但是,通常情况并非如此。【参考方案2】:

覆盖活动的dispatchTouchEvent 方法,如下所示:

@Override
public boolean dispatchTouchEvent(MotionEvent ev)      
  return true;//consume

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

返回false让它们正常工作

【讨论】:

我的 Activity 拥有一个 RecyclerView,无论返回 true 还是 false,如果我覆盖 Methode,所有触摸事件都将被禁用。你有什么想法 @K.Dexter 你可能忘了打电话给super.dispatchTouchEvent(ev)【参考方案3】:

你可以试试:

your_view.setEnabled(false);

应该禁用触摸事件。

您也可以尝试(感谢 Ercan):

@Override
public boolean dispatchTouchEvent(MotionEvent ev)      
  return true;//consume

public boolean dispatchTouchEvent(MotionEvent ev) 
    if(!onInterceptTouchEvent())
        for(View child : children)
            if(child.dispatchTouchEvent(ev))
                return true;
        
    
    return super.dispatchTouchEvent(ev);

【讨论】:

如果 ListView 是 'your_view'-ViewGroup 的子元素,这将不适用于 ListView 元素 这不会禁用子视图的触摸【参考方案4】:

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

private boolean inProgress = false;

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

【讨论】:

欢迎来到 Stack Overflow!我已经编辑了你的答案;通过将代码缩进 4 个空格,将其放入 code markdown。一般来说,在这里发布答案时,除了代码之外,最好提供一点解释。 虽然这段代码 sn-p 可以解决问题,including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。 我会反转 if 语句以避免不必要的负面影响。逻辑上等价,但减少了出错的可能性(非符号“!”很容易被忽略)。【参考方案5】:

使用这个。返回 true 表示监听器已经消费了事件,android 不需要做任何事情。

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

【讨论】:

这个答案将允许您在启用视图的同时禁用触摸事件,如果您有像我这样需要的奇怪用例。 在使用拖放的情况下很有用(我的情况)。谢谢! 在视图上工作。不在视图组上。视图组中的子视图仍然能够接收点击事件。【参考方案6】:

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

【讨论】:

我现在也在考虑这个问题,但是从孩子的角度涵盖所有内容不是很困难吗?它不会受限于其直接父级的大小吗?【参考方案7】:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                     WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

【讨论】:

【参考方案8】:

在 Kotlin 中:

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)

【讨论】:

【参考方案9】:

我制作了这个方法,非常适合我。它禁用选定视图的所有触摸事件。

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);
        
    

【讨论】:

【参考方案10】:

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

【讨论】:

【参考方案11】:

最简单的方法是

private fun setInteractionDisabled(disabled : Boolean) 
  if (disabled) 
    window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
   else 
    window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
  
 

【讨论】:

【参考方案12】:

根据您的评论:

我只是希望能够在某个时候禁用当前活动的视图

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

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

【讨论】:

【参考方案13】:

这对我有用,我创建了一个空方法并将其命名为 doNothing

   public void doNothing(View view)



然后在我想禁用触摸事件的所有对象上从onClick 事件调用此方法。 android:onClick="doNothing"

当点击或触摸事件被触发时,没有任何处理。

【讨论】:

【参考方案14】:

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

 android:shouldDisableView="True"

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

【讨论】:

以上是关于禁用所有视图的触摸事件的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中禁用 uiwebview 上的某些触摸事件

在 `touchesBegan:withEvent:` 之后禁用所有 UIPanGestureRecognizer

避免将触摸事件传递给后面的背景视图

为啥我的 UItextView 顶部的子视图没有被触摸?

如何禁用标准 UIButton 触摸事件

将触摸事件传递给多个选项之一