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

时间:2017-07-21 09:55:31

标签: android bottom-sheet

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

Link to expected behavior.

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

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

1 个答案:

答案 0 :(得分:4)

您可以通过继承BottomSheetBehavior并覆盖onTouchEvent来提早返回ACTION_UPACTION_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类处理这些事件并触发&#39;展开&#39;或者&#39;崩溃&#39;调用

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

要在工作表完全展开或折叠时将默认功能恢复为BottomSheetBehavior,您可以添加一个标记,该标记在幻灯片偏移达到特定值时设置。在以下示例中,仅当幻灯片偏移介于0.1和0.9之间时,才会忽略底部工作表ACTION_UPACTION_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);
    }
}