【问题标题】:OnTouchEvent not working on child viewsOnTouchEvent 不适用于子视图
【发布时间】:2012-06-15 14:35:46
【问题描述】:

我有一个线性布局,上面有一个按钮和一个 TextView。我为活动编写了一个 OnTouchEvent。如果我触摸屏幕,代码工作正常,但如果我触摸按钮,代码不起作用。对此有什么可能的解决方案?

public boolean onTouchEvent(MotionEvent event) {
   int eventaction=event.getAction();


   switch(eventaction)
   {
   case MotionEvent.ACTION_MOVE:
      reg.setText("hey");


   break;
   }
   return true;

  }

【问题讨论】:

  • 请粘贴您的活动代码。

标签: android ontouchlistener


【解决方案1】:
RecyclerView list_view = findViewById(R.id.list_view);
list_view.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener(){
    @Override
    public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        View child = rv.findChildViewUnder(e.getX(), e.getY());
        Log.i("Hello", "World");
        return false;
    }
});

【讨论】:

    【解决方案2】:

    使用public boolean dispatchTouchEvent(MotionEvent event) 代替onTouchEvent()

    【讨论】:

      【解决方案3】:

      你也可以试试onUserInteraction():

      @Override 
      public void onUserInteraction(){
           //your code here
           super.onUserInteraction();
      }
      

      很适合我!

      【讨论】:

        【解决方案4】:

        Activity::onTouchEvent 仅当 Activity 窗口中的视图没有消耗/处理事件时才会被调用。如果你触摸ButtonButton 将消耗事件,因此 Activity 将无法处理它。

        查看以下文章,了解有关 Android 触摸事件处理管道的更多信息。

        http://pierrchen.blogspot.jp/2014/03/pipeline-of-android-touch-event-handling.html

        【讨论】:

          【解决方案5】:

          让我对@Devunwired 的这篇出色的帖子再添加一条评论。

          如果您还在 View 上设置了 onTouchListener,那么它的 onTouch() 方法将在调度方法之后调用,但在任何 onTouchEvent() 方法之前,即在 @Devunwired 的 no.3 和 no.4 之间回答。

          【讨论】:

            【解决方案6】:

            问题在于 Android 如何处理触摸事件的操作顺序。每个触摸事件都遵循以下模式(简化示例):

            1. Activity.dispatchTouchEvent()
            2. ViewGroup.dispatchTouchEvent()
            3. View.dispatchTouchEvent()
            4. View.onTouchEvent()
            5. ViewGroup.onTouchEvent()
            6. Activity.onTouchEvent()

            但事件只会跟随链直到它们被消耗(意味着有人从 onTouchEvent() 或侦听器返回 true)。如果您只是触摸屏幕上的某个位置,则没有人对该事件感兴趣,因此它会一直流向您的代码。但是,对于按钮(或其他可点击的View),它会消耗触摸事件,因为它对它感兴趣,所以流程在第 4 行停止。

            如果您想监控进入您的 Activity 的所有触摸,您需要覆盖 dispatchTouchEvent(),因为总是首先调用,onTouchEvent() Activity 被最后调用,并且只有在没有其他人捕获该事件的情况下。但是请注意不要在此处使用事件,否则子视图将永远无法获取它们,并且您的按钮将无法点击。

            public boolean dispatchTouchEvent(MotionEvent event) {
               int eventaction=event.getAction();
            
                switch(eventaction) {
                  case MotionEvent.ACTION_MOVE:
                      reg.setText("hey");
                      break;
                  default:
                      break;
                }
            
                return super.dispatchTouchEvent(event);
            }
            

            另一种选择是将您的触摸处理代码放入自定义ViewGroup(如LinearLayout)并使用其onInterceptTouchEvent() 方法允许父视图偷走并在必要时处理触摸事件。不过要小心,因为这种交互在新的触摸事件开始之前无法撤消(一旦你窃取了一个事件,你就窃取了所有事件)。

            HTH

            【讨论】:

            • 你能提供一些我可以在我的问题中实现的代码吗?这会很有帮助
            • 已添加。此外,您可以编辑问题以包含您的问题文本和代码示例,以便将来查看此问题的人可以从答案中受益。
            • 我用你的代码在我的应用程序的屏幕之间切换。但是画面的切换是完全随机的。它不是一个固定的顺序..
            • 确保您还没有onTouchEvent() 代码,这将取代它。这听起来像是一个单独的问题,需要对您的代码进行更深入的检查。但听起来您可能需要更多地阅读有关如何进行自定义触摸处理的内容,因为如果您没有掌握所有情况,这可能会非常棘手。这是我最近做的一个演示,可以帮助你更好地理解这个过程:andevcon.com/AndevCon_III/…
            • action_move 也响应非常小的点击。我希望它应该在用户拖动屏幕时工作
            【解决方案7】:

            尝试将布局的 descendantFocusability 属性设置为 blocksDescendants

            【讨论】:

              猜你喜欢
              • 2016-07-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-29
              • 1970-01-01
              相关资源
              最近更新 更多