Що означає булеве значення, повернене з методу обробки подій в Android


110

В андроїді більшість методів прослуховування подій повертають булеве значення. Що означає це справжнє / хибне значення? що це призведе до подій, що підлягають подальшому розвитку?

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

Що стосується вищенаведеного прикладу, якщо повернути true у методі onTouch , я виявив, що кожна подія дотику (DOWN, UP, MOVE тощо) була записана відповідно до мого logView . Навпаки, якщо повернути помилково, подія DOWN буде захоплено. Отож, мабуть, повернення помилки запобіжить поширенню події. Я прав?

Крім того, у OnGestureListener багато методів також мають повернути бульне значення. Чи мають вони однакове значення?

Відповіді:


140

Якщо ви повернетесь trueз ACTION_DOWNподії, вас цікавлять решта подій у цьому жесті. "Жест" в цьому випадку означає всі події до фіналу ACTION_UPабо ACTION_CANCEL. Повернувшись falseіз ACTION_DOWNзасобу, який ви не хочете, щоб подія та інші погляди мали змогу впоратися з нею. Якщо у вас перегляди, що перекриваються, це може бути подання побратимів. Якщо ні, то він перекинеться на батьківщину.


3
adamp, чи є спосіб продовжувати приймати події І пропускати події?
— ticofab

@ticofab ні, лише батько перегляду, який наразі отримує події, може перехопити майбутні події в жесті. (Звичайно, ви завжди можете створити власну систему переадресації в батьківському режимі, але я б не рекомендував це, якщо ви дійсно не знаєте, що робите. :))
— adamp

@adamp Я не можу придумати причину, чому onTouch викликається 2 рази при поверненні true та 1 раз, коли я повертаю false.
— Bhargav Jhaveri

1
@adamp: Я повертаю false з ACTION_DOWN, але мій ACTION_UP запускається та виконується.
— Махантеш М Амбі

Я неправильно розумію цю відповідь, або всі інші ... У цій відповіді сказано, що повернення справжнього означає, що жорстка подія не споживається. Але правда зовсім зворотна.
— Кай Ван


12

Булеве значення визначає, подія споживається чи ні.

Так, ти прав. Якщо ви повернете помилковий, наступний слухач обробляє подію. Якщо він повернеться істинним, подія споживається вашим слухачем і не надсилається наступному методу.


2
Це помилково. trueозначає, що ви пожили подію та хочете, щоб решта подій в жесті - інші слухачі / перегляди не отримають події. falseозначає нехай хтось інший поводиться з подією. Це насправді трохи більш конкретно, ніж це; дивіться мою відповідь.
— adamp

Як це не зовсім те, що я сказав?
— Фальмарі

1
Те, що ви сказали, є зворотним. :)
— adamp

4

Відповідь у всьому вище правильна, але результат відрізняється, чи є "Перегляд" clickableчи ніclickable

Наприклад , у мене є LinearLayout1 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може зателефонувати більше, ніж мій журнал (це базується на тому, як ви натискаєте)

Підсумок

  • onTouchповернення trueабо перегляд є clickable , Перегляд отримає всіх onTouchEvent
  • onTouchповернення falseта перегляд немає clickable, перегляд не отримає НАСТУП на onTouchEvent (його батько може отримати його)

Сподіваюся, це допоможе
DEMO


1
Це повинна бути відповідь! Дякую за таке детальне пояснення
— Mysterious_android

1

Я втратив майже один день у усуненні несправностей, я все ж з’ясував, що моя функція onTouch викликається 2 рази при використанні true та 1 раз при використанні false.


Не могли б ви дізнатися причину?
— Bhargav Jhaveri

перевірити, event.getAction()тому що якщо ви повернетесь falseдо події ACTION_DOWN, слухач ігнорує подію
— ACTION_UP

0

З Android-документа :

Примітка: Android спочатку зателефонує обробникам подій, а потім відповідним обробникам за замовчуванням з другого визначення класу. Таким чином, повернення істини від цих слухачів події зупинить розповсюдження події для інших слухачів подій, а також заблокує зворотний виклик до обробника подій за замовчуванням у Перегляді. Тож будьте впевнені, що ви хочете припинити подію, коли ви повернетесь правдою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.