Я хочу воссоздать поведение нижнего листа, представленное в приложении "Карты Google":
Ссылка на ожидаемое поведение.
Я попытался использовать BottomSheetBehavior и пару других сторонних библиотек, таких как umano AndroidSlidingUpPanel, но проблема, которую я не мог избежать, - это все, Нижний лист между состояниями (свернутый и расширенный).
Я хотел бы иметь нижний лист, который можно плавно развернуть, сдвинув его вверх, не привязывая его к ближайшему состоянию, а вместо этого оставаясь там, где пользователь остановился при скольжении.
Android Bottom Sheet плавно расширяется, например, Google Maps
Ответ 1
Это можно сделать путем подклассификации BottomSheetBehavior
и переопределения onTouchEvent
для возврата на раннем этапе ACTION_UP
и ACTION_CANCEL
.
public class CustomBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
public CustomBottomSheetBehavior() {
super();
}
public CustomBottomSheetBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
return true;
}
return super.onTouchEvent(parent, child, event);
}
}
Это не позволяет классу BottomSheetBehavior
обрабатывать эти события и запускать вызов "expand" или "collapse".
Чтобы применить ваш CustomBottomSheetBehavior
в xml:
app:layout_behavior="com.yourpackage.CustomBottomSheetBehavior"
Чтобы восстановить функциональность по умолчанию для BottomSheetBehavior
, когда лист полностью развернут или скомпенсирован, вы можете добавить флаг, который устанавливается, когда смещение слайда достигает определенного значения. В следующем примере события нижнего листа ACTION_UP
и ACTION_CANCEL
игнорируются только тогда, когда смещение слайда находится между 0,1 и 0,9.
public class CustomBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
private boolean isExpandedOrCollapsed;
public CustomBottomSheetBehavior() {
super();
listenForSlideEvents();
}
public CustomBottomSheetBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
listenForSlideEvents();
}
void listenForSlideEvents() {
setBottomSheetCallback(new BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
isExpandedOrCollapsed = slideOffset < 0.1f || slideOffset > 0.9f;
}
});
}
@Override
public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
if (!isExpandedOrCollapsed) {
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
return true;
}
}
return super.onTouchEvent(parent, child, event);
}
}