У меня есть пользовательские цвета, установленные в моем 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>
При успешном (не полностью протестированном) изменении фона с помощью нижеприведенного значения 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();
}
Есть несколько способов применить тему во время выполнения. Один из них очень хорошо освещен здесь. Проблема с этими подходами состоит в том, что вам нужно будет воссоздать активность хотя бы одного, вызвав 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);
}
}
}
Это может звучать как большая работа. Но вам придется делать это только в том случае, если вы не хотите восстанавливать активность.