问题
What I'm trying to achieve is something like Instagram in-app web browser, used when you click an ad:
what I did, is I used a WebView bottomSheetDialogFragment, and I override onCreateDialog
to get the full screen like this :
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
BottomSheetDialog bottomSheetDialog=(BottomSheetDialog)super.onCreateDialog(savedInstanceState);
bottomSheetDialog.setOnShowListener(dialog -> {
BottomSheetDialog dialogc = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = dialogc .findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
//BottomSheetBehavior.from(bottomSheet).setSkipCollapsed(true);
//BottomSheetBehavior.from(bottomSheet).setHideable(true);
});
return bottomSheetDialog;
}
here is the result I get :
my question is, how can I get the full screen effect, or how can achieve something like instagram browser?
ps: I tried first chrome custom tabs, but I couldn't add it inside dialog fragment.
Thank you.
回答1:
In your custom BottomSheetDialogFragment you can use something like:
@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override public void onShow(DialogInterface dialogInterface) {
BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialogInterface;
setupFullHeight(bottomSheetDialog);
}
});
return dialog;
}
private void setupFullHeight(BottomSheetDialog bottomSheetDialog) {
FrameLayout bottomSheet = (FrameLayout) bottomSheetDialog.findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
ViewGroup.LayoutParams layoutParams = bottomSheet.getLayoutParams();
int windowHeight = getWindowHeight();
if (layoutParams != null) {
layoutParams.height = windowHeight;
}
bottomSheet.setLayoutParams(layoutParams);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
private int getWindowHeight() {
// Calculate window height for fullscreen use
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels;
}
回答2:
You can do it by setting peekHeight
of BottomSheetBehavior
to be equal to Resources.getSystem().getDisplayMetrics().heightPixels
:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
BottomSheetDialog bottomSheetDialog=(BottomSheetDialog)super.onCreateDialog(savedInstanceState);
bottomSheetDialog.setOnShowListener(dialog -> {
BottomSheetDialog dialogc = (BottomSheetDialog) dialog;
// When using AndroidX the resource can be found at com.google.android.material.R.id.design_bottom_sheet
FrameLayout bottomSheet = dialogc.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setPeekHeight(Resources.getSystem().getDisplayMetrics().heightPixels);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
});
return bottomSheetDialog;
}
回答3:
Proposed solutions are based on using an internal id
, since it is not on purpose exposed it could change without warning.
My solution set the layout height to the FrameLayout
but in a more abstract way, so if it changes it shouldn't break, even if the ViewGroup
type change.
override fun onStart() {
super.onStart()
val sheetContainer = requireView().parent as? ViewGroup ?: return
sheetContainer.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
}
If you take a look at the BottomSheetDialog
the private View wrapInBottomSheet
method you will see this happens to guarantee the sheet behavior. Some extra debugging, allowed me to figure the fragment View
is the direct child from the FrameLayout
everybody is finding by id.
In this way, you don't need to rely on the ID. I'm using onStart
because is defined at the point when the fragment is ready for interactions, so all should be ready.
And if you need it full height from the start (most probably)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return BottomSheetDialog(requireContext(), theme).apply {
behavior.state = BottomSheetBehavior.STATE_EXPANDED
behavior.peekHeight = //your harcoded or dimen height
}
}
回答4:
Sorry for the late answer but in your custom BottomSheetDialogFragment you can set match_parent
to layout params of bottom sheet view like this:
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = BottomSheetDialog(requireContext(), theme)
dialog.setOnShowListener {
val bottomSheetDialog = it as BottomSheetDialog
val parentLayout =
bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
parentLayout?.let { it ->
val behaviour = BottomSheetBehavior.from(it)
setupFullHeight(it)
behaviour.state = BottomSheetBehavior.STATE_EXPANDED
}
}
return dialog
}
private fun setupFullHeight(bottomSheet: View) {
val layoutParams = bottomSheet.layoutParams
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT
bottomSheet.layoutParams = layoutParams
}
Setting height to match_parent
helps your dialog to be drawn above the inset of Navigation bar
来源:https://stackoverflow.com/questions/58065771/bottomsheetdialogfragment-full-screen