2017-05-31 28 views
3

我有底部工作表,我想改變它的行爲,所以它可以像在Google地圖應用程序的主屏幕上那樣工作,您可以將它展開到任何位置並將它放在那裏,並且它不會自動粘到底部或頂部。這裏是我的佈局下表:如何使底部表單(BottomSheetBehavior)可展開到任意位置?

<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_EXPANDEDSTATE_COLLAPSED狀態的拖動結束時。

這裏是我做的嘗試,實現了可視化解釋:


正如你可以看到,底層不會自動錨定到頂部或底部,但在任何位置它留給停留。

+0

嗨,你是否能夠實現這種行爲?我也很感興趣,謝謝! – dor506

+0

@ dor506嗨,不,我正在努力實現這一目標,但我的團隊中的經理和設計人員隨時改變了需求,並決定他們需要標準的底部表單行爲:)但是,我發現爲了實現這一需求重新實現BottomSheetBehavior類;在我的情況下,我決定更改STATE_EXPANDED的邏輯,並在表單可見時分配此狀態,而不僅僅是當它粘到頂端時。或者你可以用其他方式重新思考。無論如何,我祝你好運,實施這一點。 –

回答

2

嗨亞歷克斯你可以嘗試這個代碼類似的預期行爲,它不是最優化的,但它會幫助你理解這個概念。

 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); 




      } 
     }); 
+0

感謝您的留言。它使底部表單在向上滑動時帶有「步驟」,因此它以某種方式類似於所需的行爲,但並不像應該那樣工作。雖然,它給了我一些進一步嘗試的想法。 –

+1

是的亞歷克斯你需要優化它,這是一個快速的邏輯 – Alok

+0

你知道,我已經工作了兩天了,這是一個錯誤的實現方式。看來你所能做的只是實現你自己的CoordinatorLayout.Behavior類。 –

2

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

我創建了源自設計庫的原始源代碼的概念證明。您可以查看它here。原始行爲的問題是它不允許閃爍,而且大多數方法都是私有的,所以擴展類和重寫某些方法以嘗試實現它並不會讓你感覺很差。我的實現允許可選的捕捉行爲,瞬態狀態(拖動後不自動捕捉)以及圍繞設置窺視高度和最大高度的自定義。

相關問題