防止BottomSheetDialogFragment覆盖导航栏

72

我正在使用非常朴素的代码来展示一个底部弹出式对话框片段:

class LogoutBottomSheetFragment : BottomSheetDialogFragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.view_image_source_chooser, container, false)
        return view
    }
}

这是我称呼此对话框的方式:

LogoutBottomSheetFragment().show(supportFragmentManager, "logout")

但是我得到的效果很糟糕,如下图所示。如何保持导航栏为白色(底部带有后退/主页软件按钮的栏)?

我正在使用的应用主题:

 <!-- Base application theme. -->
<style name="BaseAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
</style

<style name="AppTheme" parent="BaseAppTheme">
    <item name="android:windowNoTitle">true</item>
    <item name="windowActionBar">false</item>

    <!-- Main theme colors -->
    <!--   your app branding color for the app bar -->
    <item name="android:colorPrimary">@color/colorPrimary</item>
    <!--   darker variant for the status bar and contextual app bars -->
    <item name="android:colorPrimaryDark">@android:color/white</item>
    <!--   theme UI controls like checkboxes and text fields -->
    <item name="android:colorAccent">@color/charcoal_grey</item>

    <item name="colorControlNormal">@color/charcoal_grey</item>
    <item name="colorControlActivated">@color/charcoal_grey</item>
    <item name="colorControlHighlight">@color/charcoal_grey</item>

    <item name="android:textColorPrimary">@color/charcoal_grey</item>
    <item name="android:textColor">@color/charcoal_grey</item>

    <item name="android:windowBackground">@color/white</item>
</style>

我还尝试重写 setupDialog 方法而不是 onCreateView,但仍然发生相同的问题:

    @SuppressLint("RestrictedApi")
override fun setupDialog(dialog: Dialog, style: Int) {
    super.setupDialog(dialog, style)
    val view = View.inflate(context, R.layout. view_image_source_chooser,null)
    dialog.setContentView(view)
}

请显示 R.layout.view_image_source_chooser - kalabalik
@azizbekian 是的,我认为这是正确的方向。我编辑了我的回答。 - oferiko
你使用什么设备和操作系统版本?你是否使用任何应用程序来自定义系统导航栏等? - Przemysław Piechota. kibao
@oferiko 我在_Nexus 5X_上测试了一段示例代码,导航栏没有变灰。与您不同的是,我创建了一个扩展BottomSheetDialogFragment类的类,并覆盖了_setupDialog_方法。 - JJ86
mm setupDialog 是支持库的内部函数,请查看 IDE 警告(错误)。 - oferiko
显示剩余9条评论
14个回答

0
请使用以下API来设置setContentView,而不是重写onCreateView方法。
        val dialog = BottomSheetDialog(context)
        dialog.setContentView(R.layout.your_layout)

BottomSheetDialog.setContentView会为BottomSheetDialog设置正确的行为。您可以查看源代码:

       public void setContentView(@LayoutRes int layoutResId) {
              super.setContentView(this.wrapInBottomSheet(layoutResId, (View)null, (LayoutParams)null));
       }

       private View wrapInBottomSheet(int layoutResId, View view, LayoutParams params) {
               FrameLayout container = (FrameLayout)View.inflate(this.getContext(), layout.design_bottom_sheet_dialog, (ViewGroup)null);
               CoordinatorLayout coordinator = (CoordinatorLayout)container.findViewById(id.coordinator);
               if (layoutResId != 0 && view == null) {
                  view = this.getLayoutInflater().inflate(layoutResId, coordinator, false);
               }
               // ... more stuff
       }

0

经过一段时间的研究,这是我的解决方案。

class AboutDialog : BottomSheetDialogFragment() {

private var _binding: DialogAboutBinding? = null
private val binding get() = _binding

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    _binding = DialogAboutBinding.inflate(inflater, container, false)
    return binding!!.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val color = Color.WHITE
    val isLite = true
    dialog?.window?.run {
        navigationBarColor = color
        WindowCompat.getInsetsController(this, this.decorView).isAppearanceLightNavigationBars = isLite
    }
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

}

enter image description here

enter image description here


-2

我遇到了同样的问题。在查看来源后,我找到了一个解决方法(有点繁琐,但我没有找到其他替代方案)。

public class YourDialog extends BottomSheetDialogFragment {

    //your code

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new FitSystemWindowsBottomSheetDialog(getContext());
    }
}

public class FitSystemWindowsBottomSheetDialog extends BottomSheetDialog {

    public FitSystemWindowsBottomSheetDialog(Context context) {
        super(context);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getWindow() != null && Build.VERSION.SDK_INT >= 21) {
            findViewById(android.support.design.R.id.coordinator).setFitsSystemWindows(false);
            findViewById(android.support.design.R.id.container).setFitsSystemWindows(false);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS |
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }
}

最后,别忘了在你的对话框布局根节点添加android:fitsSystemWindows="true"
希望能帮到你。

-4

不要使用BottomSheetDialogFragment。我更喜欢通过将布局包装在协调布局中并将BottomSheetBehaiviour附加到该布局来添加底部表单

您可以参考 this 作为示例


我希望能够实现淡入淡出效果,而不必自己编写代码。如果找不到解决此问题的方法,这将是我的最后一招。 - oferiko
不可能实现,因为打开对话框会暂停当前活动,所以您将无法与该活动进行任何交互。 - Farmaan Elahi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接