Android: событие касания не достигнет детей, если затронут родитель - PullRequest
1 голос
/ 28 февраля 2020


У меня есть активность, образованная линейным макетом с четырьмя кнопками в качестве дочерних элементов; макет охватывает весь размер экрана, кнопки охватывают только половину размера экрана ( см. здесь ).

Каждая кнопка имеет сенсорный приемник, поэтому я могу обрабатывать касаться событий на всех кнопках одновременно: если, например, я касаюсь и удерживаю кнопку 1, а после касания кнопки 2, то событие onTouch кнопки 2 достигается, даже если кнопка 1 не была отпущена.

Проблема возникают, когда я касаюсь и удерживаю фон (линейный макет) и одновременно касаюсь одной из кнопок: событие onTouch не достигает кнопок; Я должен отпустить касание на фоне, чтобы кнопки работали должным образом.

Мне нужно держать телефон левой рукой на фоне и нажимать кнопки правой рукой.

Как я могу заставить это работать?

Редактировать. Как предлагается более подробно ниже.

Код активности, назначьте слушателей кнопкам. Код слушателя не имеет значения, в плохом случае метод onTouch вообще не достигается.

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_keyboard);

    // Setup keyboard listener
    KeyListener keyListener = new KeyListener();
    findViewById(R.id.key_frst).setOnTouchListener(keyListener);
    findViewById(R.id.key_scnd).setOnTouchListener(keyListener);
    findViewById(R.id.key_thrd).setOnTouchListener(keyListener);
    findViewById(R.id.key_frth).setOnTouchListener(keyListener);

}

Конфигурация активности, в этой попытке есть ConstraintLayout, содержащий CustomLinearLayout (см. Код ниже), содержащий четыре кнопки.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="false"
    android:focusable="auto"
    android:focusableInTouchMode="false"
    tools:context=".KeyboardActivity">

    <com.unimi.lim.hmi.ui.CustomLinearLayour
        android:id="@+id/keyboard_vlayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginStart="100dp"
        android:clickable="false"
        android:orientation="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <Button
            android:id="@+id/key_frth"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="@string/key_frth" />

        <Button
            android:id="@+id/key_thrd"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="@string/key_thrd" />

        <Button
            android:id="@+id/key_scnd"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="@string/key_scnd" />

        <Button
            android:id="@+id/key_frst"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="@string/key_frst"
            tools:visibility="visible" />
    </com.unimi.lim.hmi.ui.CustomLinearLayour>

</androidx.constraintlayout.widget.ConstraintLayout>

CustomLinearLayout расширяет LinearLayout, ниже единственного метода переопределения: я пытался всегда делегировать сенсорные события в макет child

    @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    // Always delegate events to child
    return false;
}

Спасибо, Daniele

1 Ответ

1 голос
/ 29 февраля 2020

При непосредственном прикосновении к LinearLayout (вне его дочерних элементов) LinearLayout потребляет все последующие касания в потоке и не предлагает их своим дочерним элементам, даже если палец тащил за ребенком. Это не зависит от значения, возвращаемого onInterceptTouchEvent(). Это имеет смысл, потому что ребенок не увидел бы исходное событие MotionEvent.ACTION_DOWN.

Когда при касании LinearLayout за пределами его дочерних элементов второй палец (указатель) касается ребенка, LinearLayout все еще потребляет последующие действия. Это также имеет смысл, поскольку второе касание может быть частью жеста на LinearLayout .

Все вышеперечисленное по умолчанию все по умолчанию. Поведение можно изменить, кодируя dispatchTouchEvent() в пользовательском LinearLayout , чтобы передать прикосновение ребенка к ребенку, вызвав для ребенка dispatchTouchEvent() для второго указателя. (Это также можно сделать в Activity , если вы не хотите настраивать представление.)

Я нашел это полезным для понимания Android сенсорная система.

...