bottomSheetDialogFragment 全屏

Abd*_*del 42 android material-design bottom-sheet material-components material-components-android

我想要实现的是类似于 Instagram 应用程序内网络浏览器,当您点击广告时使用:

Instagram 网络浏览器

我所做的,是我使用了一个 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;
}
Run Code Online (Sandbox Code Playgroud)

这是我得到的结果:

网页浏览器

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

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

谢谢你。

Gab*_*tti 72

在您的自定义中,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;
  }
Run Code Online (Sandbox Code Playgroud)

  • 无法访问“android.support.design.R.id.design_bottom_sheet”的人可以尝试以下操作:“com.google.android.material.R.id.design_bottom_sheet” (7认同)

luk*_*spp 28

抱歉回答晚了,但在您的自定义 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
}
Run Code Online (Sandbox Code Playgroud)

设置高度以match_parent帮助您的对话框绘制在导航栏的插图上方


Nat*_*yev 23

您可以通过将peekHeightof设置为BottomSheetBehavior等于来实现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;
}
Run Code Online (Sandbox Code Playgroud)

  • 使用 AndroidX 时,可以在 com.google.android.material.R.id.design_bottom_sheet 找到资源 (6认同)

cut*_*iko 19

提议的解决方案基于使用 internal id,因为它不是故意暴露的,它可以在没有警告的情况下改变。

我的解决方案FrameLayout以更抽象的方式将布局高度设置为,因此如果它发生变化,即使ViewGroup类型发生变化也不应该中断。

override fun onStart() {
    super.onStart()
    val sheetContainer = requireView().parent as? ViewGroup ?: return
    sheetContainer.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
}
Run Code Online (Sandbox Code Playgroud)

如果你在看看BottomSheetDialogprivate View wrapInBottomSheet方法,你会看到这种情况发生,以保证片状物行为。一些额外的调试,让我认为这个片段ViewFrameLayout每个人都通过 id 找到的直接子元素。

这样,您就不需要依赖 ID。我正在使用onStart因为是在片段准备好进行交互时定义的,所以一切都应该准备好了。

如果你从一开始就需要全高(很可能)

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return BottomSheetDialog(requireContext(), theme).apply {
        behavior.state = BottomSheetBehavior.STATE_EXPANDED
        behavior.peekHeight = //your harcoded or dimen height
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果有人遇到同样的问题,我会在半途释放时模式不会返回全屏。`onCreateDialog`,将 peek 设置为 `peekHeight = resources.displayMetrics.heightPixels` (2认同)

Ali*_*iSh 17

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

BottomSheetDialog dialog = (BottomSheetDialog) getDialog();
dialog.getBehavior().setState(BottomSheetBehavior.STATE_EXPANDED);
Run Code Online (Sandbox Code Playgroud)

科特林:

val dialog = dialog as BottomSheetDialog
dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
Run Code Online (Sandbox Code Playgroud)

  • 只需要大约一半的宽度 (2认同)

小智 14

这是在 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
Run Code Online (Sandbox Code Playgroud)


小智 7

最好的方法是通过 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>
Run Code Online (Sandbox Code Playgroud)

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

然后创建从 Theme.Design.BottomSheetDialog 继承的自定义主题,并设置您要使用自己的样式覆盖底部工作表的样式。也可以放在styles.xml中

<style name="Theme.MyApp.BottomSheetDialog" parent="Theme.Design.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/Widget.MyApp.BottomSheet.Modal</item>
</style>
Run Code Online (Sandbox Code Playgroud)

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

<style name="Base.Theme.MyApp" parent="Base.Theme.Root">
    ... too many other things
    <item name="bottomSheetDialogTheme">@style/Theme.MyApp.BottomSheetDialog</item>
Run Code Online (Sandbox Code Playgroud)


小智 5

我用的是这样的方式:

  • 将带有“android:layout_height=”match_parent”的视图添加到根布局中
  • 当显示对话框时(或在此之前)使用“isFitToContents = false”和“state = BottomSheetBehavior.STATE_EXPANDED”更新BottomSheetBehavior。

代码:

override fun onShow(dialog: DialogInterface?) {
    BottomSheetBehavior.from(binding?.root?.parent as View).apply {
        isFitToContents = false
        state = BottomSheetBehavior.STATE_EXPANDED
    }
}
Run Code Online (Sandbox Code Playgroud)

xml文件:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/fragment_cities_root_background">

        <View
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <!-- other views -->

    </androidx.constraintlayout.widget.ConstraintLayout >
Run Code Online (Sandbox Code Playgroud)


小智 5

只需添加以下代码行

bottomSheetDialog.getBehavior().setState(BottomSheetBehavior.STATE_EXPANDED);
Run Code Online (Sandbox Code Playgroud)

并且布局应该在里面NestedScrollView