Android: прозрачная строка состояния с динамическими цветами actionBar и DrawerLayout

у меня есть деятельность с DrawerLayout. Наш клиент требует от нас динамического изменения цвета панели действий и соответствующего цвета строки состояния этого действия в зависимости от выбранного элемента DrawerLayout. Это легко сделать. Однако моя проблема заключается в том, что я не могу сохранить прозрачность строки состояния при динамическом изменении цвета строки состояния. Когда я открываю ящик, цветная строка состояния покрывает верхнюю часть DrawerLayout как это:

wrong layout

однако, я хотел бы мой DrawerLayout выглядит так:

correct layout

это я могу сделать со следующей строкой:

<item name="android:windowTranslucentStatus">true</item>
моя проблема не в том, что я не могу установить прозрачность строки состояния. Моя проблема в том, что динамическое изменение цвета строки состояния и панели действий не работает с windowTranslucentStatus. Мой цвет строки состояния остается colorPrimaryDark (the горчично-желтоватый цвет виден в строке состояния на рисунках выше) даже после вызова getWindow().setStatusBarColor().

теперь, я следовал этой учебник и этой и этой stackoverflow вопросы среди многих других, но не удалось решить эту проблему. Все эти статьи говорят, что ActionBar переместится наверх, под строку состояния (так что строка состояния перекрывает панель действий), как только я установлю windowTranslucentStatus to true. Потом Я должен иметь возможность добавить некоторое дополнение к панели действий и просто изменить цвет панели действий также приведет к более темной строке состояния того же цвета, так как строка состояния фактически полупрозрачна и перекрывает мою панель действий. Однако по какой-то причине этого не происходит в моем случае. Панель действий остается там, где я установил fitsSystemWindows to true или false или удалить атрибут. Панель действий всегда ниже строка состояния, которая, конечно, всегда желтый, если установить прозрачность.

Я также попытался установить Альфа в цвет строки состояния при ее программном изменении. Это делает строку состояния несколько прозрачной, но выглядит странно, так как на самом деле это не темный

3 ответов


ваша проблема вызвана тем, что getWindow().setStatusBarColor() не работает с DrawerLayout. Чтобы сохранить полупрозрачную строку состояния, а также возможность изменить ее цвет, вы должны следовать приведенному ниже процессу:

добавить / изменить следующую тему в вашем v21/styles.xml файл, как показано ниже:

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

это тема, что стандартный DrawerLayout использует (при условии, конечно, что вы используете эту тему в деятельности, которая имеет DrawerLayout). Эта воля сделайте свою строку состояния полупрозрачной, как вы уже знаете.

далее удалить android:fitsSystemWindows="true" С CoordinatorLayout в своем app_bar_main.

далее, где бы вы ни меняли цвет панели инструментов / строки состояния, используйте drawerLayout.setStatusBarBackground(colorDrawable) используя тот же цвет, который вы используете для панели инструментов (при условии, конечно, что ссылка на ваш DrawerLayout называется drawerLayout). Обратите внимание, что drawerLayout.setStatusBarBackground() метод принимает Drawable "объект", в отличие от window.setStatusBarColor() метод, который берет int цвета, поэтому вы можете преобразуйте свой цвет в drawable, используя что-то вроде этого:

new ColorDrawable(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))

это позволит убедиться, что ваша строка состояния является полупрозрачным, а также дать ему возможность изменять цвета. Надеюсь, вы сможете заставить это работать.


Как doc говорит здесь, FLAG_TRANSLUCENT_STATUS не должен быть установлен.

чтобы это вступило в силу, окно должно рисовать фоны системной панели с FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS и FLAG_TRANSLUCENT_STATUS не должно быть установлено.


Я делаю это в моем приложении, как это.

<style name="AppTheme" parent="Theme.AppCompat.Dark">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>

colorPrimary установит цвет строки состояния, но только если вы перезапустите действие.

Так что установите прозрачный черный цвет, а затем в вашем коде перезапустите действие. Вы можете сделать несколько стилей в стилях с разными значениями colorPrimary, а затем в своей деятельности сделать это.

//onClick or condition statement here
setTheme(R.style.AppThemeLight);
setContentView(R.layout.activity_link_manager_light);
restart();


public void restart(){
Intent i = getBaseContext().getPackageManager()
            .getLaunchIntentForPackage( getBaseContext().getPackageName() );
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(i);
}

Я не думаю, что вам нужно сбросить contentview, если вы не переключаете макеты, а не уверены, что вы можно попробовать сбросить его на тот же макет, если он не работает без него.

Это определенно работает для меня, но я никогда не пытался использовать прозрачное значение.

вы можете использовать этот метод, чтобы сбросить всю тему приложения и переключиться на новый макет, который имеет разные цвета, жестко закодированные в него, просто оставьте все идентификаторы одинаковыми на макете, и в коде вы получите правильный идентификатор, пока вы ссылаетесь на findViewByID после того, как у вас есть setContentView на правильный макет, который имеет идентификатор, который вы где-то называете. Идентификаторы для каждого макета разные, но вы всегда получите идентификатор макета, который в настоящее время установлен с помощью setContentView во время вызова findViewByID.

вы также можете сохранить текущую тему в файл sharedpref и использовать переключатель для установки темы на applaunch перед вызовом setContentView (в противном случае цвет строки состояния не изменится)

рассмотрим этот код. Это близко к началу onCreate путь

String Theme;
    SaveData = getSharedPreferences(SaveFileName,0);
    Theme = SaveData.getString("Theme","Default Theme");
switch(Theme){
        case "Light Theme":
            setTheme(R.style.AppThemeLight);
            setContentView(R.layout.activity_link_manager_light);
            ListTextViewID = R.id.AppListTextViewLight;
            ListRowID = R.layout.app_list_item_light;
            break;

кстати я поставил apptheme прежде чем ставить на странице просмотр содержимого почему статусбар меняет цвет работы.