使用 LAYOUT_FULLSCREEN 或 LAYOUT_STABLE UI 标志时,浅色状态栏图标不会变为深色?
Light Statusbar icons won't change to dark when using LAYOUT_FULLSCREEN or LAYOUT_STABLE UI flags?
所以当我强制我的应用程序进入浅色主题时,我的应用程序 status bar
没有将其图标更改为深色。
我发现了问题的根源,即 status bar
中的图标不想在我有 SYSTEM_UI
标志时变暗 LAYOUT_STABLE
并且LAYOUT_FULLSCREEN
应用于 Activity
。当我删除这 2 个标志时,status bar
中的图标适当变暗。
但是我上面这个 "solution" 的问题是我使用了 2 个 SYSTEM_UI
标志来让我的 Activity 的内容滚动到 status bar
下面,我已将其设为半透明。除了使用我目前为此 Activity
使用的 2 SYSTEM_UI
标志之外,我还没有想出另一种方法来使我的 status bar
接受透明度并在其下方滚动内容,这些标志再次 SYSTEM_UI_FLAG_LAYOUT_STABLE
和 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
。
有人知道我该如何解决这个问题吗?
也许有人可以告诉我一种可靠的方法,让我的 status bar
接受透明度并看到内容在其下方滚动,而无需使用 SYSTEM_UI
标志?我认为这可能会解决我的问题...
我认为与分享相关的唯一代码是:
在我的MainActivity.java中,我有这个集合:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);`
在我的 styles.xml 中,我为 Light Theme
:
设置了这个主题
<!-- Toolbar/NoActionBar variant of default Light Theme -->
<style name="AppTheme_Light_NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/pure_white_transparent</item>
<item name="colorPrimaryDark">@color/pure_white_transparent</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/pure_white_transparent</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:navigationBarColor">@color/pure_white</item>
<item name="android:windowLightNavigationBar">true</item>
</style>
有什么想法吗?
好的,所以我自己想出来了。看起来我可能需要在调用 setContentView
之前设置 SYSTEM_UI
标志。不过,可能是这些更改的组合使它对我有用 - 我不完全确定。
我改变的是在调用 setContentView
:
之前使用这些标志
if (lightMode) {
setTheme(R.style.AppTheme_Light_NoActionBar);
getWindow().getDecorView().setSystemUiVisibility
(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
上面的 lightMode
是一个 SharedPreference
布尔值,如果用户在我的应用程序 toolbar
中选择了 Change theme
按钮(在黑暗中的工作方式相同mode/theme).
最后,对于我的 MainActivity
's theme, I have this style set in my styles.xml
(for API 27 and above - looks a bit different for lower Android APIs' styles.xml
):
<!-- Toolbar/NoActionBar variant of default Light Theme -->
<style name="AppTheme_Light_NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/pure_white_transparent</item>
<item name="colorPrimaryDark">@color/pure_white_transparent</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/pure_white_transparent</item>
<item name="android:navigationBarColor">@color/pure_white_transparent</item>
</style>
因为在我看来,将 SYSTEM_UI
标志设置为 LAYOUT_FULLSCREEN
和 LAYOUT_STABLE
会使 toolbar
位于 statusbar
下方,我'我们通过以下方式设置了一些适当的填充:
int statusBarHeight = getStatusBarHeight(this);
其中 getStatusBarHeight
是一种用于解释 statusbars
在不同 Android 设备上可能不同大小的方法(例如 Pixel 3XL 的较大 statusbar
)。
我从 Whosebug 的其他地方获得了这个工作方法,但忘记了在哪里,所以如果有人知道,请随时 link 它 - 方法如下:
// Gets the StatusBar's height of the particular display.
public static int getStatusBarHeight(final Context context) {
final Resources resources = context.getResources();
final int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return (int) Math.ceil(24 * resources.getDisplayMetrics().density);
} else {
return (int) Math.ceil(25 * resources.getDisplayMetrics().density);
}
}
}
然后我获取了 int statusBarHeight
的值并以编程方式将其用作我的 toolbar
的上边距:
// Setup the values for the toolbar's layout parameters.
CoordinatorLayout.LayoutParams toolbarParams = new CoordinatorLayout.LayoutParams(
CoordinatorLayout.LayoutParams.MATCH_PARENT,
CoordinatorLayout.LayoutParams.WRAP_CONTENT
);
toolbarParams.setMargins(0, statusBarHeight, 0, 0);
// Find, Assign, and Setup the Toolbar to take place of the Actionbar.
// Then inflate the proper menu to be used on-top of it, and set its layout parameters
// which have been set in the code above.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.inflateMenu(R.menu.menu_main);
getSupportActionBar().setDisplayShowTitleEnabled(true);
toolbar.setLayoutParams(toolbarParams);
最后,我确保我的应用程序的 RecyclerView
正确位于 statusbar
和 toolbar
下方,这是我通过为其设置适当的填充来实现的,也以编程方式:
// Get and set the values for the OffsetPadding for the RecyclerView to int.
int itemOffsetPaddingSide = (int) getResources().getDimension(R.dimen.item_offset);
int actionBarSize = (int) getResources().getDimension(R.dimen.actionbarSizeWithExtraPadding);
int itemOffsetPaddingTop = actionBarSize + statusBarHeight;
// Set all the OffsetPadding values to the RecyclerView programmatically, so that
// all the UI elements are padding properly, taking into account the devices screen
// density/size/resolution!
mRecyclerView.setPadding(itemOffsetPaddingSide, itemOffsetPaddingTop, itemOffsetPaddingSide, itemOffsetPaddingSide);
int itemOffsetPaddingSide
的值为 4dp
,int actionBarSize
的值为 60dp
,int itemOffsetPaddingTop
的值为 actionBarSize
和 statusBarHeight
,我们得到 56dp
加上特定设备的 statusBar
的高度(因为在 [=84= 的代码中检索并分配给 statusBarHeight
的值]).
这一切都让我的 RecyclerView
的内容可以舒适地位于 statusbar
和 toolbar
下方,并且在它们下方滚动时也可以看到,因为 bars
有 90% opacity
.
我已经独立学习 Java 编程和 Android 应用程序开发近 2 年了,虽然我为这次的成就感到自豪,但我也不确定这是在我的应用程序中实现此效果的最优雅方式。但无论哪种方式,它都有效,如果您发现它对您的应用也有用,请告诉我!
所以当我强制我的应用程序进入浅色主题时,我的应用程序 status bar
没有将其图标更改为深色。
我发现了问题的根源,即 status bar
中的图标不想在我有 SYSTEM_UI
标志时变暗 LAYOUT_STABLE
并且LAYOUT_FULLSCREEN
应用于 Activity
。当我删除这 2 个标志时,status bar
中的图标适当变暗。
但是我上面这个 "solution" 的问题是我使用了 2 个 SYSTEM_UI
标志来让我的 Activity 的内容滚动到 status bar
下面,我已将其设为半透明。除了使用我目前为此 Activity
使用的 2 SYSTEM_UI
标志之外,我还没有想出另一种方法来使我的 status bar
接受透明度并在其下方滚动内容,这些标志再次 SYSTEM_UI_FLAG_LAYOUT_STABLE
和 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
。
有人知道我该如何解决这个问题吗?
也许有人可以告诉我一种可靠的方法,让我的 status bar
接受透明度并看到内容在其下方滚动,而无需使用 SYSTEM_UI
标志?我认为这可能会解决我的问题...
我认为与分享相关的唯一代码是:
在我的MainActivity.java中,我有这个集合:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);`
在我的 styles.xml 中,我为 Light Theme
:
<!-- Toolbar/NoActionBar variant of default Light Theme -->
<style name="AppTheme_Light_NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/pure_white_transparent</item>
<item name="colorPrimaryDark">@color/pure_white_transparent</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/pure_white_transparent</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:navigationBarColor">@color/pure_white</item>
<item name="android:windowLightNavigationBar">true</item>
</style>
有什么想法吗?
好的,所以我自己想出来了。看起来我可能需要在调用 setContentView
之前设置 SYSTEM_UI
标志。不过,可能是这些更改的组合使它对我有用 - 我不完全确定。
我改变的是在调用 setContentView
:
if (lightMode) {
setTheme(R.style.AppTheme_Light_NoActionBar);
getWindow().getDecorView().setSystemUiVisibility
(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
上面的 lightMode
是一个 SharedPreference
布尔值,如果用户在我的应用程序 toolbar
中选择了 Change theme
按钮(在黑暗中的工作方式相同mode/theme).
最后,对于我的 MainActivity
's theme, I have this style set in my styles.xml
(for API 27 and above - looks a bit different for lower Android APIs' styles.xml
):
<!-- Toolbar/NoActionBar variant of default Light Theme -->
<style name="AppTheme_Light_NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/pure_white_transparent</item>
<item name="colorPrimaryDark">@color/pure_white_transparent</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/pure_white_transparent</item>
<item name="android:navigationBarColor">@color/pure_white_transparent</item>
</style>
因为在我看来,将 SYSTEM_UI
标志设置为 LAYOUT_FULLSCREEN
和 LAYOUT_STABLE
会使 toolbar
位于 statusbar
下方,我'我们通过以下方式设置了一些适当的填充:
int statusBarHeight = getStatusBarHeight(this);
其中 getStatusBarHeight
是一种用于解释 statusbars
在不同 Android 设备上可能不同大小的方法(例如 Pixel 3XL 的较大 statusbar
)。
我从 Whosebug 的其他地方获得了这个工作方法,但忘记了在哪里,所以如果有人知道,请随时 link 它 - 方法如下:
// Gets the StatusBar's height of the particular display.
public static int getStatusBarHeight(final Context context) {
final Resources resources = context.getResources();
final int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return (int) Math.ceil(24 * resources.getDisplayMetrics().density);
} else {
return (int) Math.ceil(25 * resources.getDisplayMetrics().density);
}
}
}
然后我获取了 int statusBarHeight
的值并以编程方式将其用作我的 toolbar
的上边距:
// Setup the values for the toolbar's layout parameters.
CoordinatorLayout.LayoutParams toolbarParams = new CoordinatorLayout.LayoutParams(
CoordinatorLayout.LayoutParams.MATCH_PARENT,
CoordinatorLayout.LayoutParams.WRAP_CONTENT
);
toolbarParams.setMargins(0, statusBarHeight, 0, 0);
// Find, Assign, and Setup the Toolbar to take place of the Actionbar.
// Then inflate the proper menu to be used on-top of it, and set its layout parameters
// which have been set in the code above.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.inflateMenu(R.menu.menu_main);
getSupportActionBar().setDisplayShowTitleEnabled(true);
toolbar.setLayoutParams(toolbarParams);
最后,我确保我的应用程序的 RecyclerView
正确位于 statusbar
和 toolbar
下方,这是我通过为其设置适当的填充来实现的,也以编程方式:
// Get and set the values for the OffsetPadding for the RecyclerView to int.
int itemOffsetPaddingSide = (int) getResources().getDimension(R.dimen.item_offset);
int actionBarSize = (int) getResources().getDimension(R.dimen.actionbarSizeWithExtraPadding);
int itemOffsetPaddingTop = actionBarSize + statusBarHeight;
// Set all the OffsetPadding values to the RecyclerView programmatically, so that
// all the UI elements are padding properly, taking into account the devices screen
// density/size/resolution!
mRecyclerView.setPadding(itemOffsetPaddingSide, itemOffsetPaddingTop, itemOffsetPaddingSide, itemOffsetPaddingSide);
int itemOffsetPaddingSide
的值为 4dp
,int actionBarSize
的值为 60dp
,int itemOffsetPaddingTop
的值为 actionBarSize
和 statusBarHeight
,我们得到 56dp
加上特定设备的 statusBar
的高度(因为在 [=84= 的代码中检索并分配给 statusBarHeight
的值]).
这一切都让我的 RecyclerView
的内容可以舒适地位于 statusbar
和 toolbar
下方,并且在它们下方滚动时也可以看到,因为 bars
有 90% opacity
.
我已经独立学习 Java 编程和 Android 应用程序开发近 2 年了,虽然我为这次的成就感到自豪,但我也不确定这是在我的应用程序中实现此效果的最优雅方式。但无论哪种方式,它都有效,如果您发现它对您的应用也有用,请告诉我!