20

I recently used android.support.design.widget.BottomSheetDialogFragment. I wanted to do something which is similar to the Google contact app, its BottomSheet can overlay the toolbar and statusbar. However, when I use the BottomSheetDialogFragment to implement this, it turns out to this: My Implementation

As you can see the activity's toolbar is still visible. Here is my code of the BottomSheetDialogFragment:

public class KeyDetailFragment extends BottomSheetDialogFragment {
    private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                dismiss();
            }
        }

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

        }
    };

    @Override
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, style);
        View contentView = View.inflate(getActivity(), R.layout.sheet_key, null);
        dialog.setContentView(contentView);
        View parent = (View) contentView.getParent();
        parent.setFitsSystemWindows(true);
        BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(parent);
        contentView.measure(0, 0);
bottomSheetBehavior.setPeekHeight(contentView.getMeasuredHeight());

        CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) parent.getLayoutParams();
        if (params.getBehavior() instanceof BottomSheetBehavior) {
                 ((BottomSheetBehavior)params.getBehavior()).setBottomSheetCallback(mBottomSheetBehaviorCallback);
        }
        params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
        parent.setLayoutParams(params);
    }
}

I referred to the source and I found an attribute interests me:

private static int getThemeResId(Context context, int themeId) {
    if (themeId == 0) {
        // If the provided theme is 0, then retrieve the dialogTheme from our theme
        TypedValue outValue = new TypedValue();
        if (context.getTheme().resolveAttribute(
                R.attr.bottomSheetDialogTheme, outValue, true)) {
            themeId = outValue.resourceId;
        } else {
            // bottomSheetDialogTheme is not provided; we default to our light theme
            themeId = R.style.Theme_Design_Light_BottomSheetDialog;
        }
    }
    return themeId;
}

the attribute bottomSheetDialogTheme here may change the bottom sheet's style but I don't know how to change it, and I doubt whether this would work. Can someone give me solution about achieving it that it can overlay the toolbar and statusbar?

Jian Guo
  • 708
  • 1
  • 9
  • 19

3 Answers3

21

Try this. It works for me.

@Override
public void setupDialog(Dialog dialog, int style) {
    super.setupDialog(dialog, style);
    View inflatedView = View.inflate(getContext(), R.layout.fragment_coupon, null);
    dialog.setContentView(inflatedView);


    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) inflatedView.getParent()).getLayoutParams();
    CoordinatorLayout.Behavior behavior = params.getBehavior();

    if (behavior != null && behavior instanceof BottomSheetBehavior) {
        ((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
    }

    View parent = (View) inflatedView.getParent();
    parent.setFitsSystemWindows(true);
    BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(parent);
    inflatedView.measure(0, 0);
    DisplayMetrics displaymetrics = new DisplayMetrics();        getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int screenHeight = displaymetrics.heightPixels;
    bottomSheetBehavior.setPeekHeight(screenHeight);

    if (params.getBehavior() instanceof BottomSheetBehavior) {
        ((BottomSheetBehavior)params.getBehavior()).setBottomSheetCallback(mBottomSheetBehaviorCallback);
    }

    params.height = screenHeight;
    parent.setLayoutParams(params);
}
Vaigunth
  • 250
  • 4
  • 11
  • 1
    One thing to note with this solution is the displayMetrics.heightPixels will include the notification tray height so this will cut off the bottom slightly. I used this to calculate the height of the notification tray. `private int getStatusBarHeight() { Rect rectangle = new Rect(); Window window = getActivity().getWindow(); window.getDecorView().getWindowVisibleDisplayFrame(rectangle); return rectangle.top; }` – C Nick Apr 13 '17 at 20:32
  • Edit: DisplayMetrics displaymetrics = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); To: DisplayMetrics displaymetrics = getActivity().getResources().getDisplayMetrics() – roghayeh hosseini Aug 15 '18 at 04:45
  • Is it handle able with coordinator layout and appbar in xml? – Mahdi Dec 10 '19 at 04:39
2

Was not able to find the solution to this problem, but can suggest an alternate that helped me serve the same purpose. Here's the reference : http://www.hidroh.com/2016/06/17/bottom-sheet-everything/

The article explains creating a bottom sheet activity and adding the backdrop shadow with it.

nipun.birla
  • 719
  • 5
  • 19
  • The given reference is surely an alternative way to my purpose, adding a backdrop shadow is really tricky. – Jian Guo Jul 20 '16 at 19:40
  • This answer does not address the problem in this question at all which is "Make bottomSheetDialog full screen over status bar". Nothing in that article helps with solving that, and it just wasted my time clicking into it. Also, pasting a link without any attempt at showing the answer here on SO is poor practice. – Vin Norman Jan 27 '22 at 06:40
1

This was easiest and worked for me, just extend BottomSheetDialog and set BottomSheetBehavior to BottomSheetBehavior.STATE_EXPANDED

Little hack is layout name android.support.design.R.id.design_bottom_sheet is taken from android support design library

class BottomSheetDialogExpanded(context: Context) : BottomSheetDialog(context) {

    private lateinit var mBehavior: BottomSheetBehavior<FrameLayout>

    override fun setContentView(view: View) {
        super.setContentView(view)
        val bottomSheet = window.decorView.findViewById<View>(android.support.design.R.id.design_bottom_sheet) as FrameLayout
        mBehavior = BottomSheetBehavior.from(bottomSheet)
        mBehavior.state = BottomSheetBehavior.STATE_EXPANDED
    }

    override fun onStart() {
        super.onStart()
        mBehavior.state = BottomSheetBehavior.STATE_EXPANDED
    }
}
Akhil
  • 6,667
  • 4
  • 31
  • 61