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