У меня есть нижний лист, вложенный в другой нижний лист (FrameLayouts
с использованием поведения макета BottomSheet
)
У меня также есть несколько «просмотров» (FrameLayouts
), к которым прикреплены прослушиватели щелчков, чтобы раскрыть нижние листы соответственно при нажатии.
Таким образом, в приложении есть три основных экрана. «Основной контейнер», затем первый «нижний лист», который можно развернуть на весь экран, а затем внизу первого нижнего листа, является второй нижний лист, который также можно развернуть в полноэкранном режиме.
Проблема:
Когда я добавляю RecyclerView
во вложенный нижний лист «контейнер», перетаскивание перестает работать для второго обзора (Sheet 2 Peek). Если я удалю обзор ClickListener
или RecyclerView
, все будет работать отлично.
Желаемый результат:
Оба нижних листа должны оставаться перетаскиваемыми, а обзорные панели должны иметь возможность щелкнуть, чтобы развернуть их родительский нижний лист. Нижний лист должен реагировать на вложенные прокрутки, как обычно.
Я попытался удалить ClickListener
и использовать вместо этого сенсорные жесты, но ничего из того, что я пробовал, похоже, не помогает.
Я использую v25.3.1
из библиотеки поддержки дизайна, и я могу воспроизвести эту проблему на Galaxy S4 с версией 4.4.4 и Nexus 6P с версией 7.1.2. (У меня нет других доступных устройств).
Я также создал тестовый проект на github для всех, кто хочет поближе познакомиться: https://github.com/timusus/bottomsheet-test
Вот пара скриншотов, демонстрирующих макет:
Структура макета выглядит так (некоторый код для ясности опущен):
<CoordinatorLayout>
<FrameLayout
android:id="@+id/mainContainer"
android:layout_height="match_parent"/>
<FrameLayout
android:id="@+id/sheet1"
android:layout_height="match_parent"
app:layout_behavior="CustomBottomSheetBehavior"
app:behavior_peekHeight="64dp">
<FrameLayout
android:id="@+id/sheet1Container"
android:layout_height="match_parent"/>
<CoordinatorLayout>
<FrameLayout
android:id="@+id/sheet2
android:layout_height="match_parent"
app:layout_behavior="CustomBottomSheetBehavior"
app:behavior_peekHeight="64dp">
<FrameLayout
android:id="@+id/sheet2Container"
android:layout_height="match_parent">
<!-- Problematic RecyclerView -->
<RecyclerView
android:layout_height="match_parent"/>
</FrameLayout>
<!-- Problematic Click Listener on this view -->
<FrameLayout
android:id="@+id/sheet2PeekView"
android:layout_height=64dp"/>
</FrameLayout>
</CoordinatorLayout>
<FrameLayout
android:id="@+id/sheet1PeekView"
android:layout_height=64dp"/>
</FrameLayout>
</CoordinatorLayout/>
CustomBottomSheetBehavior
- это всего лишь простой подкласс BottomSheetBehavior
, который не позволяет первому листу перехватывать события касания, если второй лист разворачивается или перетаскивается. Это позволяет перетаскивать второй лист из «развернутого» в «свернутый» без одновременного свертывания первого листа.
public class CustomBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
private boolean allowDragging = true;
public void setAllowDragging(boolean allowDragging) {
this.allowDragging = allowDragging;
}
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
if (!allowDragging) {
return false;
}
return super.onInterceptTouchEvent(parent, child, event);
}
}
Я не верю, что настройка BottomSheetBehavior
имеет отношение к этой проблеме, но для полноты, вот как она используется:
FrameLayout sheet1 = (FrameLayout) findViewById(R.id.sheet1);
bottomSheetBehavior1 = (CustomBottomSheetBehavior) BottomSheetBehavior.from(sheet1);
FrameLayout sheet2 = (FrameLayout) findViewById(R.id.sheet2);
bottomSheetBehavior2 = (CustomBottomSheetBehavior) BottomSheetBehavior.from(sheet2);
bottomSheetBehavior2.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
//If the second sheet is expanded or dragging, don't allow the first sheet to respond to touch events.
if (newState == BottomSheetBehavior.STATE_EXPANDED || newState == BottomSheetBehavior.STATE_DRAGGING) {
bottomSheetBehavior1.setAllowDragging(false);
} else {
bottomSheetBehavior1.setAllowDragging(true);
}
}
Кажется, я не могу понять, связано ли это с onInterceptTouchEvent
из BottomSheet
, вложенной обработкой прокрутки внутренних событий касания RecyclerView
, View.ClickListener
кражи, комбинацией вышеперечисленного или чем-то еще.
Любая помощь приветствуется.