Что означает логическое значение, возвращаемое из метода обработки событий в Android

В Android большинство методов прослушивания событий возвращают логическое значение. Что означает это истинное / ложное значение? к чему это приведет к событиям подпоследовательности?

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

Что касается приведенного выше примера, если в методе onTouch возвращается true, я обнаружил, что каждое сенсорное событие (ВНИЗ, ВВЕРХ, ПЕРЕМЕЩЕНИЕ и т. Д.) Было зафиксировано в соответствии с моим logView. Напротив, если вернуть false, то только событие DOWN было зафиксировано. Таким образом, кажется, что возвращение false будет препятствовать распространению события. Я прав?

Кроме того, в OnGestureListener многие методы также должны возвращать логическое значение. Они имеют одинаковое значение?

6 ответов

Решение

Если вы вернетесь true из ACTION_DOWN событие вас интересует остальные события в этом жесте. "Жест" в этом случае означает все события до финала ACTION_UP или же ACTION_CANCEL, возврате false из ACTION_DOWN означает, что вы не хотите событие, и другие представления будут иметь возможность обработать его. Если у вас перекрывающиеся представления, это может быть одноуровневое представление. Если нет, то это будет пузыриться до родителя.

Из документации: http://developer.android.com/reference/android/view/View.OnTouchListener.html, android.view.MotionEvent)

"Истинно, если слушатель использовал событие, иначе ложно".

Если вы вернете true, событие будет обработано. Если false, он перейдет к следующему слою вниз.

Логическое значение определяет, используется ли событие или нет.

Да вы правы Если вы возвращаете false, следующий слушатель обрабатывает событие. Если он возвращает true, событие используется вашим слушателем и не отправляется следующему методу.

Все вышеприведенные ответы верны, но результат будет другим, если вид 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>

В Activity у меня есть такой код

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, view не получит NEXT onTouchEvent (родитель может его получить)

Надеюсь, это поможет
DEMO

Я потерял почти один день на устранение неполадок, но я обнаружил, что моя функция onTouch вызывается 2 раза при использовании true и 1 раз при использовании false.

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

Примечание. Android сначала вызывает обработчики событий, а затем соответствующие обработчики по умолчанию из определения класса. Таким образом, возврат true из этих прослушивателей событий остановит распространение события на другие прослушиватели событий, а также заблокирует обратный вызов для обработчика событий по умолчанию в представлении. Поэтому будьте уверены, что хотите прекратить событие, когда вернете true.

Другие вопросы по тегам