Подтвердить что ты не робот

Android Bottom Sheet плавно расширяется, например, Google Maps

Я хочу воссоздать поведение нижнего листа, представленное в приложении "Карты Google":

Ссылка на ожидаемое поведение.

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

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

4b9b3361

Ответ 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);
    }
}