Що означає булеве значення, повернене з методу обробки подій в 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.