Светлые значки строки состояния не изменятся на темные при использовании флагов пользовательского интерфейса LAYOUT_FULLSCREEN или LAYOUT_STABLE? - PullRequest
0 голосов
/ 05 апреля 2019

Итак, у меня проблема с тем, что status bar моего приложения не меняет свои иконки на темные, когда я перевожу свое приложение в светлую тему.

Я обнаружил корень проблемы, котораячто значки в status bar не хотят становиться темными, когда к Activity применены SYSTEM_UI флаги LAYOUT_STABLE и LAYOUT_FULLSCREEN.Когда я убираю эти 2 флага, значки в status bar становятся темными.

Но моя проблема с этим «решением» выше заключается в том, что я использую флаги 2 SYSTEM_UI, чтобы прокрутить содержимое моей Деятельности ниже status bar, который я сделал полупрозрачным.Я не нашел другого способа заставить мой status bar принять прозрачность и прокрутить содержимое под ним, кроме использования 2 SYSTEM_UI флагов, которые у меня есть для этого Activity, которые, опять же, 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>

Есть идеи?

1 Ответ

0 голосов
/ 08 апреля 2019

Хорошо, так что я понял это самостоятельно.Похоже, мне, вероятно, нужно было установить флаги SYSTEM_UI перед вызовом setContentView.Хотя, это может быть сочетание этих изменений, которое заставило меня работать - я не совсем уверен.

Что я изменил, так это использование этих флагов перед вызовом 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, которое я установил, если пользователь выбрал кнопку Change theme в моем приложении toolbar (работает аналогично для темного режима / темы).

И наконец, для моей темы MainActivity этот стиль установлен в моем styles.xml (для API 27 и выше - выглядит немного иначе для более низких API Android '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 (например, в пикселях 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 моего приложения правильно расположено под 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 для конкретного устройства:(из-за значений, извлеченных и присвоенных statusBarHeight в коде далее по почте).

Все это позволяет содержимому моего RecyclerView удобно сидеть ниже statusbar и toolbar, а также быть видимым при прокрутке под ними обоими, поскольку оба bars имеют 90% opacity.

Я изучаю Java-программирование и разработку приложений для Android уже почти 2 года независимо, и хотя я горжусь тем, куда я пришел в это время, я также не уверен, что этосамый элегантный способ добиться этого эффекта в моем приложении.Но в любом случае, это работает, и если вы найдете это полезным для вашего приложения, дайте мне знать!

...