从Android中的事件处理方法返回的布尔值的含义是什么


110

在android中,大多数事件侦听器方法都返回布尔值。正确/错误值是什么意思?这将导致子序列事件吗?

class MyTouchListener implements OnTouchListener {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        logView.showEvent(event);
        return true;
    }
}

对于上面的示例,如果在onTouch方法中返回true ,我发现根据我的logView捕获了每个触摸事件(DOWN,UP,MOVE等)。相反,如果返回false,则首先捕获DOWN事件。因此,似乎return false将阻止事件传播。我对么 ?

此外,在OnGestureListener中,许多方法也必须返回布尔值。它们具有相同的含义吗?

Answers:


140

如果您true从某个ACTION_DOWN事件返回,则对该手势中的其他事件感兴趣。在这种情况下,“手势”表示所有事件,直到决赛ACTION_UPACTION_CANCELfalse从某种ACTION_DOWN方式返回意味着您不希望该事件发生,其他视图将有机会处理该事件。如果您有重叠的视图,则这可能是一个兄弟视图。如果没有,它将冒泡给父母。


3
adamp,有没有办法继续接收事件并让事件通过?
ticofab 2014年

@ticofab否,只有当前正在接收事件的视图的父级才能拦截手势中将来的事件。(当然,您始终可以在父视图中构建自己的重定向系统,但除非您真的知道自己在做什么,否则我不建议您这样做::))
adamp 2014年

@adamp我无法想到为什么在返回true时调用onTouch 2次而仅在返回false时调用1次onTouch的原因。
Bhargav Jhaveri 2014年

1
@adamp:我从ACTION_DOWN返回false,但是我的ACTION_UP被触发并执行。
Mahantesh M Ambi 2014年

我得到的答复是错误的还是其他所有人都是...该答复说,返回true表示不消耗困难的事件。但是事实是完全相反的。
Kai Wang


12

布尔值确定是否使用事件。

是的,你是正确的。如果返回false,则下一个侦听器处理该事件。如果返回true,则事件由您的侦听器使用,并且不会发送到下一个方法。


2
这是错误的。true表示您消耗了该事件,并希望以手势显示其余事件-其他侦听器/视图将不会接收该事件。false意味着让别人来处理事件。实际上,它比这更具体。看我的答案。
adamp 2010年

那不完全是我所说的吗?
Falmarri 2010年

1
你所说的相反。:)
adamp 2010年

4

以上所有的答案是正确的,但结果不同的是,如果该视图clickable或不clickable

例如,我有一个LinearLayout包含1 Button和1 TextView这样的

<LinearLayout
    android:id="@+id/linearlayout_root"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#0aa"
    android:orientation="vertical">

    <Button
        android:id="@+id/button_click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="40dp"
        android:text="Button Click"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/textview_click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="40dp"
        android:text="TextView Click"
        android:textSize="20sp"
        android:background="#e4e4e4"
        />

</LinearLayout>

在活动中,我有类似的代码

class MainActivity : AppCompatActivity() {
    val TAG = "TAG"

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<LinearLayout>(R.id.linearlayout_root).setOnTouchListener { v, event ->
            Log.i(TAG, "LinearLayout onTouch event " + getDisplayAction(event.action))
            false
        }

        findViewById<Button>(R.id.button_click).setOnTouchListener { v, event ->
            Log.i(TAG, "Button onTouch event " + getDisplayAction(event.action))
            false
        }

        findViewById<TextView>(R.id.textview_click).setOnTouchListener { v, event ->
            Log.i(TAG, "TextView onTouch event " + getDisplayAction(event.action))
            false
        }
    }

    private fun getDisplayAction(action: Int): String {
        return when (action) {
            MotionEvent.ACTION_DOWN -> "DOWN"
            MotionEvent.ACTION_MOVE -> "MOVE"
            MotionEvent.ACTION_UP -> "UP"
            MotionEvent.ACTION_CANCEL -> "CANCEL"
            MotionEvent.ACTION_OUTSIDE -> "OUTSIDE"
            else -> "UNKNOWN"
        }
    }
}

案例1 Linear onTouch return **FALSE**Button onTouch return **FALSE**TextView onTouch return **FALSE**

点击按钮

I/TAG: Button onTouch eventDOWN
I/TAG: Button onTouch eventMOVE
I/TAG: Button onTouch eventUP

点击TextView

TAG: TextView onTouch eventDOWN
TAG: LinearLayout onTouch eventDOWN

点击LinearLayout

TAG: LinearLayout onTouch eventDOWN

案例2 Linear onTouch return **FALSE**Button onTouch return **TRUE**TextView onTouch return **TRUE**

点击按钮

Similar to case 1

点击TextView

TAG: TextView onTouch event DOWN
TAG: TextView onTouch event MOVE
TAG: TextView onTouch event UP

点击LinearLayout

Similar to case 1

案例3 Linear onTouch return **TRUE**Button onTouch return **FALSE**TextView onTouch return **FALSE**

点击按钮

Similar to case 1

点击TextView

TAG: TextView onTouch event DOWN
TAG: LinearLayout onTouch event DOWN
TAG: LinearLayout onTouch event MOVE
TAG: LinearLayout onTouch event UP

点击LinearLayout

TAG: LinearLayout onTouch event DOWN
TAG: LinearLayout onTouch event MOVE
TAG: LinearLayout onTouch event UP

注意

  • 默认TextView值为not clickable,如果我们设置android:clickable="true"为xml 设置时,它将变为可点击textView.setOnClickListener(...)
  • 调试时,event MOVE可以调用的日志超过我的日志(取决于您的点击方式)

摘要

  • onTouchreturn true或view是clickable ,View将接收全部 onTouchEvent
  • onTouch返回false并且视图不是clickable,视图将不会收到NEXT onTouchEvent(它的父级可能会收到)

希望它能帮助
演示


1
这应该是答案!感谢您提供如此详细的说明
Mysterious_android

1

我花了将近一天的时间进行故障排除,但我仍然发现,使用true时,我的onTouch函数被调用2次,使用false时被调用1次。


你能找出原因吗?
Bhargav Jhaveri 2014年

检查event.getAction()原因,因为如果您返回falseACTION_DOWN事件,则侦听器将忽略ACTION_UP事件
doodeec 2014年

0

来自Android文档

注意:Android将首先调用事件处理程序,然后再从类定义中调用适当的默认处理程序。这样,从这些事件侦听器返回true将停止将事件传播到其他事件侦听器,还将阻止对View中默认事件处理程序的回调。所以一定要在返回true时终止事件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.