2017-08-28 11 views
0

GoogleデザインライブラリのBottomSheetBehaviorを使用すると、下のシートが同じように他のビューを「カバー」するようにデフォルトの動作があるように見えます。CoordinatorLayout私は、FAB(または適切に定義されたCoordinatorLayout.Behaviorの他のビュー)をシートの上部に固定し、シートが伸びるにつれてスライドさせることができます。これはいいですが、私が望むのはビューを「折りたたむ」ボトムシートが拡大して視差効果を示します。Android - 下のシートが別のビューをカバーするように視差効果を追加する方法

Googleマップでのこの効果は、私が探しているものと似ています。それは、視差効果として始まり、その後、ちょうどボトムシート「カバー」を有するに切り替わりマップ一度特定のスクロール位置に到達した:

enter image description here

私が試したことの一つ(私は最初から疑われてもそれは動作しません)、私のBottomSheetBehavior.BottomSheetCallbackonSlideの呼び出しでプログラムで上の視界の高さを設定していた。これはやや成功しましたが、動きはGoogle Mapsほど滑らかではありませんでした。

誰かが効果がどのように達成されたか考えているなら、私はそれをたくさんいただきたいと思います!

+0

いくつかの[ライブラリ](https://github.com/wasabeef/awesome-android-ui)。 –

答えて

5

もう少し実験/研究の後で、私はこのポストから気づいた How to make custom CoordinatorLayout.Behavior with parallax scrolling effect for google MapView?私の問題の大きな部分は視差効果を理解していないということです。

public class CollapseBehavior<V extends ViewGroup> extends CoordinatorLayout.Behavior<V>{ 


    public CollapseBehavior(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    } 

    @Override 
    public boolean onDependentViewChanged(CoordinatorLayout parent, V child, View dependency) { 
    if (isBottomSheet(dependency)) { 
     BottomSheetBehavior behavior = ((BottomSheetBehavior) ((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior()); 

     int peekHeight = behavior.getPeekHeight(); 
     // The default peek height is -1, which 
     // gets resolved to a 16:9 ratio with the parent 
     final int actualPeek = peekHeight >= 0 ? peekHeight : (int) (((parent.getHeight() * 1.0)/(16.0)) * 9.0); 
     if (dependency.getTop() >= actualPeek) { 
      // Only perform translations when the 
      // view is between "hidden" and "collapsed" states 
      final int dy = dependency.getTop() - parent.getHeight(); 
      ViewCompat.setTranslationY(child, dy/2); 
      return true; 
     } 
    } 

    return false; 
    } 

    private static boolean isBottomSheet(@NonNull View view) { 
    final ViewGroup.LayoutParams lp = view.getLayoutParams(); 
    if (lp instanceof CoordinatorLayout.LayoutParams) { 
     return ((CoordinatorLayout.LayoutParams) lp) 
       .getBehavior() instanceof BottomSheetBehavior; 
    } 
    return false; 
    } 


} 

はその後、私のレイアウトXMLで、私は私のメインビューの app:layout_behaviorを設定します。私は気づいたらボトムシートが拡大したときに、私のメインビューに視差を適用するカスタム動作を作成するのは簡単でした com.mypackage.CollapseBehaviorapp:layout_anchorを私のボトムシートビューにすると、 onDependentViewChangedコールバックが発生します。この効果は、ビューのサイズを変更しようとするよりもはるかに滑らかでした。私は BottomSheetBehavior.BottomSheetCallbackを使用する私の最初の戦略に戻っても、このソリューションと同様に動作すると思われます。

編集:リクエストごとに、関連するXMLは以下のとおりです。実行時にMapFragment@+id/map_containerに追加しますが、これは静的イメージのようにそのコンテナにドロップするものでも機能します。 LocationListFragmentも同様に、それがまだBottomSheetBehavior

<android.support.design.widget.CoordinatorLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:id="@+id/fragment_coordinator"> 
     <FrameLayout 
      android:id="@+id/map_container" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_gravity="top" 
      app:layout_anchor="@+id/list_container" 
      app:layout_behavior="com.mypackage.behavior.CollapseBehavior"/> 

     <fragment 
      android:name="com.mypackage.fragment.LocationListFragment" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:id="@+id/list_container" 
      app:layout_behavior="android.support.design.widget.BottomSheetBehavior"/> 


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

これはしばらく前のことですが、これもあなたのXMLを投稿してもらえますか? – Pythogen

+1

問題なし!私はそれを追加しました –

0

パトリック・グレイソンのポストは非常に有用だった持っているとして、任意のビューまたは断片と置換することができます。私の場合でも、マップのサイズを変更するものが必要でした。上記のソリューションを採用して、翻訳の代わりにサイズを変更しました。他の人が同様の解決策を探しているかもしれません。

public class CollapseBehavior<V extends ViewGroup> extends CoordinatorLayout.Behavior<V> { 

private int pixels = NO_RESIZE_BUFFER; // default value, in case getting a value from resources bites the dust. 

private static final int NO_RESIZE_BUFFER = 200; //The amount of dp to not have the bottomsheet ever push away. 

public CollapseBehavior(Context context, AttributeSet attrs) 
{ 
    super(context, attrs); 
    pixels = (int)convertDpToPixel(NO_RESIZE_BUFFER,context); 
} 

@Override 
public boolean onDependentViewChanged(CoordinatorLayout parent, V child, View dependency) { 
    // child is the map 
    // dependency is the bottomSheet 
    if(isBottomSheet(dependency)) 
    { 
     BottomSheetBehavior behavior = ((BottomSheetBehavior) ((CoordinatorLayout.LayoutParams)dependency.getLayoutParams()).getBehavior()); 

     int peekHeight; 
     if (behavior != null) { 
      peekHeight = behavior.getPeekHeight(); 
     } 
     else 
      return true; 

     if(peekHeight > 0) { // Dodge the case where the sheet is hidden. 

      if (dependency.getTop() >= peekHeight) { // Otherwise we'd completely overlap the map 

       if(dependency.getTop() >= pixels) { // On resize when we have more than our NO_RESIZE_BUFFER of dp left. 
        if(dependency.getTop() > 0) { // Don't want to map to be gone completely. 
         CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) child.getLayoutParams(); 
         params.height = dependency.getTop(); 
         child.setLayoutParams(params); 
        } 
        return true; 
       } 
      } 
     } 
    } 
    return false; 
} 

private static float convertDpToPixel(float dp, Context context) 
{ 
    float densityDpi = context.getResources().getDisplayMetrics().densityDpi; 
    return dp * (densityDpi/DisplayMetrics.DENSITY_DEFAULT); 
} 

private static boolean isBottomSheet(@NonNull View view) 
{ 
    final ViewGroup.LayoutParams lp = view.getLayoutParams(); 
    if(lp instanceof CoordinatorLayout.LayoutParams) 
    { 
     return ((CoordinatorLayout.LayoutParams) lp).getBehavior() instanceof BottomSheetBehavior; 
    } 
    return false; 
} 
} 

とレイアウト...助けることができる

<FrameLayout 
    android:id="@+id/flMap" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_gravity="top" 
    android:layout_margin="0dp" 
    app:layout_anchor="@+id/persistentBottomSheet" 
    app:layout_behavior="com.yoursite.yourapp.CollapseBehavior"> 

    <fragment 
     android:id="@+id/mapDirectionSummary" 
     android:name="com.google.android.gms.maps.SupportMapFragment" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     tools:context="com.yoursite.yourapp.YourActivity" /> 

</FrameLayout> 

<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:id="@+id/persistentBottomSheet" 
app:behavior_peekHeight="@dimen/bottom_sheet_peek_height" 
app:behavior_hideable="false" 
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior" 
    tools:context="com.yoursite.yourapp.YourActivity"> 

<!-- Whatever you want in the bottom sheet. --> 

</android.support.constraint.ConstraintLayout> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <android.support.v7.widget.CardView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_margin="8dp" 
     app:cardElevation="8dp" 
     app:cardBackgroundColor="#324"> 

     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="56dp" 
      android:background="?attr/colorPrimary" 
      android:theme="@style/ThemeOverlay.AppCompat.ActionBar" 
      app:popupTheme="@style/Theme.AppCompat.Light"> 

      <EditText 
       android:id="@+id/txtSearch" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:background="@android:color/transparent" 
       android:ems="10" 
       android:inputType="text" 
       android:maxLines="1" /> 


     </android.support.v7.widget.Toolbar> 
    </android.support.v7.widget.CardView> 


</LinearLayout> 
関連する問題