Android Bottom Sheet平滑扩展,就像谷歌地图一样

sup*_*oje 22 android bottom-sheet

我想重新创建Google地图应用中提供的底部表格行为:

链接到预期的行为.

我已经尝试过使用BottomSheetBehavior和其他一些第三方库,比如umano AndroidSlidingUpPanel,但我无法避免的问题是它们都在状态之间捕捉底层(折叠和扩展).

我希望有一个底板,可以通过向上滑动平滑地展开,而不会卡到最近的状态,而是保持用户停止滑动的位置.

Tim*_*eed 4

您可以通过子类化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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以防止BottomSheetBehavior类处理这些事件并触发“展开”或“折叠”调用。

要在 xml 中应用您的CustomBottomSheetBehaviorapp:layout_behavior="com.yourpackage.CustomBottomSheetBehavior"


要在工作表完全展开或折叠时恢复默认功能BottomSheetBehavior,您可以添加一个在幻灯片偏移达到特定值时设置的标志。在以下示例中,仅当幻灯片偏移量在 0.1 到 0.9 之间时才会忽略底部工作表ACTION_UP和事件。ACTION_CANCEL

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);
    }
}
Run Code Online (Sandbox Code Playgroud)