如何使底页(BottomSheetBehavior)可扩展到任意位置?

时间:2017-05-31 01:58:56

标签: android google-maps bottom-sheet

我有底页,我想改变它的行为,以便它可以在Google地图应用程序的主屏幕上工作,在那里你可以将它扩展到任何位置并将其保留在那里并且它不会自动粘贴到底部或顶部。这是我的布局与底页:

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.gms.maps.MapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <View
        android:id="@+id/shadow"
        android:layout_width="match_parent"
        android:layout_height="16dp"
        android:background="@drawable/shape_gradient_top_shadow"
        app:layout_anchor="@+id/map_bottom_sheet" />


    <LinearLayout
        android:id="@+id/map_bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:fillViewport="false"
        android:orientation="vertical"
        app:behavior_peekHeight="50dp"
        android:background="@color/lightGray"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

        <include layout="@layout/bottom_sheet_top_buttons"/>
        <android.support.v4.widget.NestedScrollView
            android:id="@+id/bottom_sheet_content_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/lightGray"/>

    </LinearLayout>

</android.support.design.widget.CoordinatorLayout>

在拖拉结束时,我本质上需要消除强制 STATE_EXPANDED STATE_COLLAPSED 状态。

以下是我试图实现的目标的视觉解释:


如您所见,底部页面不会自动锚定到顶部或底部,而是保持在它剩下的任何位置。

3 个答案:

答案 0 :(得分:5)

android.support.design.widget.BottomSheetBehavior复制代码以制作您自己的自定义行为。然后修改onViewReleased()方法,该方法负责拖动结束后工作表的移动。除了现有状态之外,您还必须引入新状态 - 状态有助于恢复位置,并让其他人知道您的工作表目前处于getState()状态。

@Override
public void onViewReleased(View releasedChild, float xVel, float yVel) {
    int top;
    @State int targetState;

    // Use the position where the drag ended as new top
    top = releasedChild.getTop();

    // You have to manage the states here, too (introduce a new one)
    targetState = STATE_ANCHORED;

    if (mViewDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top)) {
        setStateInternal(STATE_SETTLING);
        ViewCompat.postOnAnimation(releasedChild, new SettleRunnable(releasedChild, targetState));

    } else {
        setStateInternal(targetState);
    }
}

答案 1 :(得分:2)

您好Alex可以尝试使用此代码来获得类似的预期行为,但它并不是优化的,但它可以帮助您理解这个概念。

     final DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
 bottomSheetBehavior.setPeekHeight(200);
// set callback for changes
        bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {

                Log.d(TAG, "onStateChanged: " + bottomSheet.getY() + "::" + bottomSheet.getMeasuredHeight() + " :: " + bottomSheet.getTop());

            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {


                ViewGroup.LayoutParams params = bottomSheet.getLayoutParams();
                params.height = Math.max(0, metrics.heightPixels - (int) bottomSheet.getTop());
                bottomSheet.setLayoutParams(params);




            }
        });

答案 2 :(得分:2)

我创建了一个源自设计库中的原始源代码的概念证明。您可以查看here。原始行为的问题是它不允许flings,并且大多数方法都是私有的,因此扩展类并覆盖某些方法以尝试实现它也不会让你走得很远。我的实现允许可选的捕捉行为,瞬态状态(拖动后不会自动捕捉)以及围绕设置窥视高度和最大高度的自定义。