package com.otaliastudios.bottomsheetcoordinatorlayout; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.design.widget.BottomSheetBehavior; import android.support.design.widget.CoordinatorLayout; import android.support.v4.os.ParcelableCompat; import android.support.v4.os.ParcelableCompatCreatorCallbacks; import android.support.v4.view.AbsSavedState; import android.support.v4.view.ViewCompat; import android.support.v4.view.WindowInsetsCompat; import android.util.AttributeSet; import android.view.View; import java.lang.reflect.Field; /** * This: * - tries to fix the hideable bug * - ensures that any inset is passed to our bottom sheet view before it is consumed by some other. * * @param <V> bottom sheet root view, typically {@link BottomSheetCoordinatorLayout} */ // link to bug https://code.google.com/p/android/issues/detail?id=207191&thanks=207191&ts=1460894786 public class BottomSheetInsetsBehavior<V extends View> extends BottomSheetBehavior<V> { private final static String TAG = BottomSheetInsetsBehavior.class.getSimpleName(); public BottomSheetInsetsBehavior() {} public BottomSheetInsetsBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @NonNull @Override public WindowInsetsCompat onApplyWindowInsets(CoordinatorLayout coordinatorLayout, V child, WindowInsetsCompat insets) { // Steal the inset and dispatch to view. ViewCompat.dispatchApplyWindowInsets(child, insets); // Pass unconsumed insets. return super.onApplyWindowInsets(coordinatorLayout, child, insets); } @Override public Parcelable onSaveInstanceState(CoordinatorLayout parent, V child) { if (getState() == STATE_SETTLING) { try { Field f = BottomSheetBehavior.class.getDeclaredField("mState"); f.setAccessible(true); f.setInt(BottomSheetInsetsBehavior.this, STATE_HIDDEN); } catch (Exception e) { e.printStackTrace(); } } return new SavedState(super.onSaveInstanceState(parent, child), isHideable()); } @Override public void onRestoreInstanceState(CoordinatorLayout parent, V child, Parcelable state) { SavedState ss = (SavedState) state; super.onRestoreInstanceState(parent, child, ss.getSuperState()); setHideable(ss.hideable); } public static class SavedState extends AbsSavedState { boolean hideable; public SavedState(Parcel source, ClassLoader classLoader) { super(source, classLoader); hideable = source.readInt() == 1; } public SavedState(Parcelable superState, boolean hideable) { super(superState); this.hideable = hideable; } @Override public void writeToParcel(Parcel out, int flags) { super.writeToParcel(out, flags); out.writeInt(hideable ? 1 : 0); } public static final Creator<SavedState> CREATOR = ParcelableCompat.newCreator( new ParcelableCompatCreatorCallbacks<SavedState>() { @Override public SavedState createFromParcel(Parcel in, ClassLoader loader) { return new SavedState(in, loader); } @Override public SavedState[] newArray(int size) { return new SavedState[size]; } }); } }