Нажмите на верхнюю половину кнопки - не работает?

У меня есть 4 Относительные макеты: (как вы можете видеть в анимации)

  • Зеленый RelativeView
  • "Тип что-то и значки" RelativeView
  • Серая функция RelativeView
  • Нижнее текстовое окно

Каждый RelativeView является "ниже" предыдущего относительного представления.

enter image description here

По дизайну, когда два внутренних вида закрыты, кнопка должна быть наполовину сверху над зеленым, а нижняя часть наполовину над текстом (как показано в анимации )

Хорошо, поэтому я добавил кнопку, которая находится внутри "нижнего текстового представления"

Но для того, чтобы дно было только наполовину ниже над представлением, я добавил отрицательную маржу:

Итак здесь без:

enter image description here

И здесь он с отрицательным полем (желаемый результат)

enter image description here

Поэтому, когда я нажимал кнопку, я просто скрывал/показывал (+ анимацию с android:animateLayoutChanges="true") внутренние 2 средние просмотры

Итак, где проблема?

Вопрос

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

Но если я удаляю отрицательный запас и кнопка полностью находится в его контейнере - тогда кнопка полностью нажимается на 100% (как верхняя половина, так и нижняя половина)

Как вы можете видеть в анимации (последние кадры) - когда я нажимаю верхнюю половину - ничего не происходит....

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

Возможно, я принял неправильный первоначальный подход?

nb: немного больше визуализации структуры:

enter image description here

Ответ 1

Поместите свою кнопку в качестве родственника в RelativeLayouts, а не в качестве ребенка. Это работает так, как вы этого хотите.

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true">![enter image description here][1]

    <RelativeLayout
        android:id="@+id/red"
        android:background="@android:color/holo_red_dark"
        android:layout_width="match_parent"
        android:layout_height="100dp">

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/green"
        android:layout_below="@id/red"
        android:background="@android:color/holo_green_dark"
        android:layout_width="match_parent"
        android:layout_height="100dp">

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/blue"
        android:background="@android:color/holo_blue_dark"
        android:layout_below="@id/green"
        android:layout_width="match_parent"
        android:layout_height="100dp">

    </RelativeLayout>

    <Button
        android:id="@+id/button"
        android:layout_centerHorizontal="true"
        android:layout_below="@id/green"
        android:layout_width="wrap_content"
        android:text="Hide Green"
        android:layout_marginTop="-24dp"
        android:layout_height="wrap_content"/>

</RelativeLayout>

Похоже на это, и кнопка перемещается вверх/вниз, поскольку setVisibility переключается между GONE/VISIBLE для зеленого RelativeLayout

Looks like this and the button moves up/down as setVisibility is toggled between GONE/VISIBLE for green RelativeLayout

Ответ 2

Ваша кнопка принадлежит нижнему RL. Когда маршруты android ACTION_DOWN проверяет границы макета и выдает события для просмотра (VG), в которых внутри координат события. Затем VG организует для него событие, на котором дети основаны на его координатах.

Итак, когда вы нажимаете на верхнюю часть кнопки касания, заданную серым RL, и кнопка, которая принадлежит синему RL, не получает ее. Фактически событие, данное Window → Root ViewGroup → Some Other ViewGroup → View. А маршрутизация происходит на основе координат. Это верно для ACTION_DOWN, который начинает касаться, но не все MotionEvent обрабатываются таким образом.

В качестве решения вы можете переместить кнопку в другую группу, которая может правильно настроить событие касания. Или, возможно, попробуйте использовать сенсорных делегатов.