bottomSheetDialogFragment全屏

时间:2019-09-23 15:34:06

标签: android material-design bottom-sheet material-components-android material-components

我想要实现的是类似于Instagram应用内网络浏览器的功能,该功能可在您点击广告时使用:

Instagram web browser

我做了什么,是使用WebView bottomSheetDialogFragment,还是重写onCreateDialog来获得全屏显示,如下所示:

@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;
}

这是我得到的结果:

web browser

我的问题是,如何获得全屏效果,或者如何实现instagram浏览器之类的功能?

ps:我先尝试了chrome自定义标签,但无法将其添加到对话框片段中。

谢谢。

8 个答案:

答案 0 :(得分:11)

很抱歉,您的答案很晚,但是您可以在自定义BottomSheetDialogFragment中设置match_parent来设置底部工作表视图的参数,如下所示:

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
}

将高度设置为match_parent可帮助您将对话框绘制在导航栏的插入上方

答案 1 :(得分:7)

在您的自定义BottomSheetDialogFragment中,您可以使用类似的内容:

  @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 :(得分:3)

最好的方法是通过XML

通过覆盖默认BottomSheet的属性(例如在styles.xml中)来自定义

<style name="Widget.MyApp.BottomSheet.Modal" parent="Widget.MaterialComponents.BottomSheet.Modal">
    <item name="behavior_skipCollapsed">true</item>
    <item name="behavior_fitToContents">true</item>
    <item name="behavior_peekHeight">1000dp</item> // yep, that helped to skip collapsed state at initial
    <item name="behavior_hideable">true</item>
</style>

进入Widget.MaterialComponents.BottomSheet.Modal以查看可以修改哪些设置。

Then create custom theme inherited from Theme.Design.BottomSheetDialog and set that you want to override bottom sheet's style with you own. Also can be placed in styles.xml

<style name="Theme.MyApp.BottomSheetDialog" parent="Theme.Design.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/Widget.MyApp.BottomSheet.Modal</item>
</style>

最后,在“活动”主题或“应用程序”主题中为底页对话框定义新创建的主题,该主题放置在themes.xml中(希望您遵循Google关于包装样式和主题的建议)

<style name="Base.Theme.MyApp" parent="Base.Theme.Root">
    ... too many other things
    <item name="bottomSheetDialogTheme">@style/Theme.MyApp.BottomSheetDialog</item>

答案 3 :(得分:2)

您可以通过将peekHeight中的BottomSheetBehavior设置为等于Resources.getSystem().getDisplayMetrics().heightPixels

@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 bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
        bottomSheetBehavior.setPeekHeight(Resources.getSystem().getDisplayMetrics().heightPixels);
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
    });
    return bottomSheetDialog;
}

答案 4 :(得分:0)

这是您在 kotlin 中的操作方法,

val dialog = super.onCreateDialog(savedInstanceState)
dialog.setOnShowListener {
    val bottomSheetDialog = it as BottomSheetDialog
    val parentLayout = bottomSheetDialog.findViewById<View>(
        com.google.android.material.R.id.design_bottom_sheet
    )
    parentLayout?.let { bottomSheet ->
        val behaviour = BottomSheetBehavior.from(bottomSheet)
        val layoutParams = bottomSheet.layoutParams
        layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT
        bottomSheet.layoutParams = layoutParams
        behaviour.state = BottomSheetBehavior.STATE_EXPANDED
    }
}
return dialog

答案 5 :(得分:0)

在我使用 kotlin 的情况下

   private fun exerciseDialog() {
                val dialogBinding: DialogExerciseBinding = DataBindingUtil.inflate(
                    LayoutInflater.from(requireContext()), R.layout.dialog_exercise, null, false
                )
                val mDialog = BottomSheetDialog(requireContext())
                mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
                mDialog.setContentView(dialogBinding.root)
                mDialog.setCanceledOnTouchOutside(true)
        
                val parentLayout =
                    mDialog.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
                }
        
                mDialog.show()
        
            }
        
            private fun setupFullHeight(bottomSheet: View) {
                val layoutParams = bottomSheet.layoutParams
                layoutParams.height = (getScreenHeight(requireActivity()) * .90).toInt()
                bottomSheet.layoutParams = layoutParams
            }

  fun getScreenHeight(activity: Activity): Int {
        val outMetrics = DisplayMetrics()

        return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            val display = activity.display
            display?.getRealMetrics(outMetrics)
            outMetrics.heightPixels
        } else {
            @Suppress("DEPRECATION")
            val display = activity.windowManager.defaultDisplay
            @Suppress("DEPRECATION")
            display.getMetrics(outMetrics)

            outMetrics.heightPixels
        }
    }

答案 6 :(得分:0)

您可以通过将对话框的状态更改为 STATE_EXPANDED 来实现:

BottomSheetDialog dialog = (BottomSheetDialog) getDialog();
dialog.getBehavior().setState(BottomSheetBehavior.STATE_EXPANDED);

科特林:

val dialog = dialog as BottomSheetDialog
dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED

答案 7 :(得分:0)

来自官方 Material-Components github 的漂亮回答

您所要做的就是一些魔法 - 将此添加到您的应用主题/样式

<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="enableEdgeToEdge">true</item>

全屏模式

<块引用>

在 API 21 及以上,BottomSheet 将全屏呈现(边缘 到边缘)如果导航栏是透明的,并且 enableEdgeToEdge 是 真的。如果有任何一个,它可以自动添加插图 paddingBottomSystemWindowInsets, paddingLeftSystemWindowInsets, paddingRightSystemWindowInsets 或 paddingTopSystemWindowInsets 是 在样式中设置为 true,或者通过更新传递给 构造函数,或通过更新指定的默认样式 主题中的bottomSheetDialogTheme 属性。

BottomSheetDialog 也会在顶部添加填充 BottomSheet 在状态栏下方滑动,防止内容被 画在它下面。