浅色状态栏图标在使用LAYOUT_FULLSCREEN或LAYOUT_STABLE UI 标志时不会变为深色?



所以我在强制我的应用进入浅色主题时,我的应用程序status bar没有将其图标更改为深色。

我发现了问题的根源,即当我LAYOUT_STABLESYSTEM_UI标志并LAYOUT_FULLSCREEN应用于Activity时,status bar中的图标不想变暗。当我删除这两个标志时,status bar中的图标正常变暗。

但是我对上面这个"解决方案"的问题是我正在使用 2 个SYSTEM_UI标志,以使我的活动内容滚动到status bar下方,我已经将其设置为半透明。除了使用我目前为此Activity拥有的 2 个SYSTEM_UI标志之外,我还没有找到另一种方法让我的status bar接受透明度并让内容滚动到它下面,它们再次SYSTEM_UI_FLAG_LAYOUT_STABLESYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

有没有人知道我如何解决这个问题?

也许有人可以向我展示一种可靠的方法,让我的status bar接受透明度,并看到内容在其下方滚动,而无需使用SYSTEM_UI标志?我想这可能会解决我的问题...

我认为唯一与共享相关的代码是:

在我的主活动.java中,我有这个集合:

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);`

在我的风格中.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按钮(深色模式/主题的工作方式相同)。

最后,对于我MainActivity的主题,我在styles.xml中设置了这种样式(对于 API 27 及更高版本 - 对于较低的 Android APIstyles.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_FULLSCREENLAYOUT_STABLE会使toolbar位于statusbar下方,我通过以下方式设置了一些适当的填充:

int statusBarHeight = getStatusBarHeight(this);其中getStatusBarHeight是一种用于解释不同Android设备上可能不同大小statusbars的方法(例如Pixel 3XL的较大statusbar)。

我从 StackOverflow 上的其他地方得到了这个工作方法,但忘记了在哪里,所以如果有人知道,请随时链接它 - 下面的方法:

// 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正确位于statusbartoolbar下方,我通过设置适当的填充来实现这一点,也是以编程方式完成的:

// 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,通过将actionBarSizestatusBarHeight结合起来,我们得到56dp加,无论特定设备的statusBar有多高(因为检索的值并分配给statusBarHeight在帖子后面的代码中

)。这一切都允许我的RecyclerView的内容舒适地位于statusbartoolbar下方,并且在滚动时在它们下面可见,因为两个bars都有90% opacity

我已经独立学习 Java 编程和 Android 应用程序开发近 2 年了,虽然我为这次的工作感到自豪,但我也不确定这是在我的应用程序中实现这种效果的最优雅的方式。但无论哪种方式,它都可以工作,如果您发现它对您的应用程序也很有用,请告诉我!

最新更新