изменить цвета в styles.xml, которые установлены в colors.xml

1

У меня есть пользовательские цвета, установленные в моем colors.xml согласно ниже, однако, возможно ли изменить/обновить цвет в моем узле темы styles.xml согласно ниже;

colors.xml

<resources>
    <color name="themeBackground">#000000</color>
    <color name="darkColor">#000000</color>
    <color name="lightColor">#ffffff</color>
<resources>

и измените вручную в моем v21\styles.xml согласно ниже, как используется в

//used in activity
onCreate().setTheme(R.style.DarkTheme);

v21\styles.xml

<style name="DarkTheme">
    <!-- change themeBackground manually here -->
    <item name="themeBackground">@color/darkColor</item>
</style>

<style name="LightTheme">
    <!-- change themeBackground manually here -->
    <item name="themeBackground">@color/lightColor</item>
</style>

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

<item name="colorPrimary">@color/lightColor</item>
Теги:
colors
styles

2 ответа

1

При успешном (не полностью протестированном) изменении фона с помощью нижеприведенного значения values \ themes.xml & values \ attrs.xml + values \ colors.xml

*Ensure any themes created in values\styles.xml are not duplicated in themes.xml(ie same key name <style name="LightLoginThemeV3">)*

добавлено ниже в values \ colors.xml (должно уже существовать...)

<!-- light Theme colors -->
<color name="lightBackgroundPrimaryV3">@color/white</color>
<color name="lightBackgroundSecondaryV3">@color/lighter_grey</color>
<color name="lightBackgroundAltV3">@color/lighter_grey</color>
<color name="lightBackgroundAltAlphaV3">#809E9E9E</color>
<color name="lightBackgroundLightV3">#80FFFFFF</color>
<color name="lightThemePrimaryColourV3">#01aac4</color>
<color name="lightThemeSecondaryColourV3">#025f8b</color>
<color name="lightThemeDarkPrimaryColourV3">@color/white</color>
<color name="lightThemeDarkSecondaryColourV3">@color/lighter_grey</color>

<!-- dark Theme colors -->
<color name="darkBackgroundPrimaryV3">#241e45</color>
<color name="darkBackgroundSecondaryV3">#2f2856</color>
<color name="darkBackgroundAltV3">#483e81</color>
<color name="darkBackgroundAltAlphaV3">#80483e81</color>
<color name="darkBackgroundLightV3">#f4f3f3</color>
<color name="darkThemePrimaryColourV3">#01aac4</color>
<color name="darkThemeSecondaryColourV3">#025f8b</color>
<color name="darkThemeDarkPrimaryColourV3">#2f2856</color>
<color name="darkThemeDarkSecondaryColourV3">#50448f</color>

values \ attrs.xml (создайте attrs.xml в папке значений, если она не существует)

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- background color keys -->
    <attr name="basePrimaryBackgroundColour" format="reference|color"/>
    <attr name="baseSecondaryBackgroundColour" format="reference|color"/>

</resources>

values \ themes.xml (создайте attrs.xml в папке значений, если она не существует)

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="LightLoginThemeV3">

        <!-- keys from values/attrs.xml file -->
        <!-- background color keys -->
        <!-- using light Theme colors via @color -->
        <item name="basePrimaryBackgroundColour">@color/lightBackgroundPrimaryV3</item>
        <item name="baseSecondaryBackgroundColour">@color/lightBackgroundSecondaryV3</item>

        <item name="windowNoTitle">true</item>
        <!-- Support library compatibility -->
        <item name="windowActionBar">false</item>
        <item name="android:windowBackground">@color/backgroundSecondaryV3</item>
        <item name="android:popupBackground">@color/backgroundSecondaryV3</item>

        <!-- EditText Fields -->
        <item name="colorControlNormal">@color/medium_grey</item>
        <item name="colorControlActivated">@color/themePrimaryColourV3</item>
        <item name="colorControlHighlight">@color/themePrimaryColourV3</item>

    </style>

    <style name="DarkLoginThemeV3">

        <!-- keys from values/attrs.xml file -->
        <!-- background color keys -->
        <!-- using dark Theme colors via @color -->
        <item name="basePrimaryBackgroundColour">@color/darkBackgroundPrimaryV3</item>
        <item name="baseSecondaryBackgroundColour">@color/darkBackgroundSecondaryV3</item>

        <item name="android:windowNoTitle">true</item>
        <!-- Support library compatibility -->
        <item name="windowActionBar">false</item>
        <item name="android:windowBackground">@color/colorTrans</item>
        <item name="android:popupBackground">@color/darkist_grey</item>

        <!-- EditText Fields -->
        <item name="colorControlNormal">@color/dark_grey</item>
        <item name="colorControlActivated">@color/colorPrimary</item>
        <item name="colorControlHighlight">@color/colorPrimary</item>

    </style>

</resources>

и в моем связанном файле макета установите фон так...

 //key from values/attrs.xml file
 android:background="?attr/basePrimaryBackgroundColour"

и в моей деятельности по методу onCreate() (и методу onResume()), на лету установить тему из values \ themes.xml через ниже...

if(darkTheme){
    setTheme(R.style.DarkLoginThemeV3);
}else{
    setTheme(R.style.LightLoginThemeV3);
}

и в моей деятельности, через событие clickListner, на лету меняем тему из values \ themes.xml через ниже...

if(darkTheme){
    setTheme(R.style.DarkLoginThemeV3);
    recreate();
}else{
    setTheme(R.style.LightLoginThemeV3);
    recreate();
}
0

Есть несколько способов применить тему во время выполнения. Один из них очень хорошо освещен здесь. Проблема с этими подходами состоит в том, что вам нужно будет воссоздать активность хотя бы одного, вызвав recreate(). Но вы можете столкнуться со сценарием, в котором воссоздание деятельности неосуществимо, возможно, из-за его зависимости от данных или неэффективности существующего архитектурного шаблона.

Есть также некоторые другие способы, которые будут работать без воссоздания активности: рекурсивный поиск взглядов и применение темы. Чтобы иметь возможность сделать это, первое ограничение должно иметь все пользовательские представления.

Для каждого представления фреймворка или группы просмотра определите пользовательский вид, как показано ниже:

class CustomTextView extends AppCompatTextView {}

Теперь вам понадобится интерфейс, подобный приведенному ниже примеру, который можно включить в представление и запустить при динамическом изменении темы.

interface Painter {
  void applyTheme(int theme)
}

Реализуйте это в своем пользовательском классе представления, как показано ниже:

class CustomTextView extends AppCompatTextView implements Painter {
     @Override
     public void applyTheme(int theme) {
          switch (theme) { ... }
     }
}

И где-нибудь в своей деятельности, рекурсивно находите представления, которые реализуют Painter и запускают applyTheme как applyTheme ниже:

public void onChangeThemeClick(int selectedTheme){
     View rootView = findViewById(android.R.id.content);
     paintRecurively(rootView,selectedTheme);
}

public void paintRecurively(View view, int theme) {
   //if view implements painter, trigger the method
   if(view instanceof Painter){
     (Painter)view.applyTheme(theme);
   }
   //if view is viewgroup then further call this method for its children.
   if(view instanceof ViewGroup){
      ViewGroup vg = (ViewGroup)view;
      for(...childCount of vg){
          paintRecurively(vg.getChildAt(i),theme);
      }
   }

}

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

  • 0
    Хорошо знаете метод воссоздания () и его ограничения, как вы уже заявили.
  • 1
    Хорошо. Я думал, что было бы хорошо оставить здесь оба пути для справки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню