ofe*_*iko 24 android navigationbar android-layout android-view bottom-sheet
我正在使用非常天真的代码来显示底部对话框片段:
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
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我调用此对话框的方式:
LogoutBottomSheetFragment().show(supportFragmentManager, "logout")
Run Code Online (Sandbox Code Playgroud)
但是我在下面的图片中看到了这个可怕的东西.如何将导航栏保持为白色(背面/主页软件按钮所在的底栏)?
我正在使用的应用主题:
<!-- 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>
Run Code Online (Sandbox Code Playgroud)
我也尝试覆盖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)
}
Run Code Online (Sandbox Code Playgroud)
Yos*_*sef 29
我知道这里已经有很多解决方案,但所有这些对我来说似乎都太多了,所以我在这里找到了这个非常简单的解决方案,归功于Arthur Nagy:
只需覆盖 BottomSheetDialogFragment 中的 getTheme 方法:
override fun getTheme(): Int = R.style.Theme_NoWiredStrapInNavigationBar
Run Code Online (Sandbox Code Playgroud)
在styles.xml中:
<style name="Theme.NoWiredStrapInNavigationBar" parent="@style/Theme.Design.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:navigationBarColor">@color/bottom_sheet_bg</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
Run Code Online (Sandbox Code Playgroud)
您还可以通过更改资产文件夹中的颜色@color/bottom_sheet_bg
来添加对夜间模式的支持values-night
Den*_*ura 22
我遇到了同样的问题,我终于找到了一个非hacky或需要一定数量的代码的解决方案.
此方法使用LayerDrawable替换窗口背景,LayerDrawable由两个元素组成:背景暗淡和导航栏背景.
@RequiresApi(api = Build.VERSION_CODES.M)
private void setWhiteNavigationBar(@NonNull Dialog dialog) {
Window window = dialog.getWindow();
if (window != null) {
DisplayMetrics metrics = new DisplayMetrics();
window.getWindowManager().getDefaultDisplay().getMetrics(metrics);
GradientDrawable dimDrawable = new GradientDrawable();
// ...customize your dim effect here
GradientDrawable navigationBarDrawable = new GradientDrawable();
navigationBarDrawable.setShape(GradientDrawable.RECTANGLE);
navigationBarDrawable.setColor(Color.WHITE);
Drawable[] layers = {dimDrawable, navigationBarDrawable};
LayerDrawable windowBackground = new LayerDrawable(layers);
windowBackground.setLayerInsetTop(1, metrics.heightPixels);
window.setBackgroundDrawable(windowBackground);
}
}
Run Code Online (Sandbox Code Playgroud)
方法"setLayerInsetTop"需要API 23,但这很好,因为在Android O(API 26)中引入了暗导航栏图标.
因此,解决方案的最后一部分是从底层的onCreate方法中调用此方法.
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setWhiteNavigationBar(dialog);
}
return dialog;
}
Run Code Online (Sandbox Code Playgroud)
我希望它有所帮助,如果您发现此解决方案不起作用的设备或案例,请告诉我.
无需代码!使用材质组件:
<style name="Theme.YourApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
...
<item name="bottomSheetDialogTheme">@style/ThemeOverlay.YourApp.BottomSheetDialog</item>
</style>
Run Code Online (Sandbox Code Playgroud)
<style name="Widget.YourApp.BottomSheet" parent="Widget.MaterialComponents.BottomSheet"/>
Run Code Online (Sandbox Code Playgroud)
<style name="ThemeOverlay.YourApp.BottomSheetDialog" parent="@style/ThemeOverlay.MaterialComponents.BottomSheetDialog">
<item name="bottomSheetStyle">@style/Widget.YourApp.BottomSheet</item>
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">?colorSurface</item>
</style>
Run Code Online (Sandbox Code Playgroud)
有一种方法可以避免更改 Java/Kotlin 代码,现在这个问题可以在 XML 中完全解决:
<style name="MyTheme" parent="Theme.MaterialComponents">
<item name="bottomSheetDialogTheme">@style/BottomSheet</item>
</style>
<style name="BottomSheet" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">?android:colorBackground</item>
<item name="android:navigationBarDividerColor">?android:colorBackground</item>
</style>
Run Code Online (Sandbox Code Playgroud)
我也有一个问题,我的主题/样式没有应用于里面的视图BottomSheetDialogFragment
,这是我在我的基础中修复它的方法BottomSheetDialogFragment
:
override fun onGetLayoutInflater(savedInstanceState: Bundle?): LayoutInflater {
val inflater = super.onGetLayoutInflater(savedInstanceState)
val wrappedContext = ContextThemeWrapper(requireContext(), R.style.My_Theme)
return inflater.cloneInContext(wrappedContext)
}
Run Code Online (Sandbox Code Playgroud)
来自j2esu的答案效果很好。但是,如果您坚持使用“全白”导航栏,则必须忽略其中的一部分。
请注意,此解决方案适用于Android O(API 26),因为此版本中引入了深色导航栏图标。在较旧的版本上,您会在白色背景上得到白色图标。
你需要:
android:fitsSystemWindows="true"
到对话框布局的根目录。Window
你的Dialog
正确。将此代码放入onStart
您的的孩子BottomSheetDialogFragment
。如果您使用设计库而不是材料库,请使用android.support.design.R.id.container
。
@Override
public void onStart() {
super.onStart();
if (getDialog() != null && getDialog().getWindow() != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Window window = getDialog().getWindow();
window.findViewById(com.google.android.material.R.id.container).setFitsSystemWindows(false);
// dark navigation bar icons
View decorView = window.getDecorView();
decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
}
}
Run Code Online (Sandbox Code Playgroud)
结果可能如下所示:
在中BottomSheetDialogFragment
,唯一需要做的就是将基础容器设置CoordinatorLayout
fitSystemWindows
为false
。
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(view!!.parent.parent.parent as View).fitsSystemWindows = false
}
Run Code Online (Sandbox Code Playgroud)
view
是你的布局view.parent
是包含您的视图的FrameLayoutview.parent.parent
是个 CoordinatorLayout
view.parent.parent.parent
是默认情况下CoordinatorLayout
为其fitsSystemWindow
设置的容器true
。这样可以确保将整体BottomSheetDialogFragment
绘制在导航栏下方。然后,您可以相应fitsSystemWindows
地将设置为自己的容器。
从其他答案中您尤其不需要的是:
getWindow()
或getDialog()
,此解决方案与BottomSheetDialogFragment
创建配合使用onCreateView
,我没有检查onCreateDialog
。
归档时间: |
|
查看次数: |
6915 次 |
最近记录: |