Змініть тему діяльності програмно


121

У деяких випадках мені потрібно видалити тему діалогу зі своєї діяльності, але це, здається, не працює. Ось приклад

Перша діяльність:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startActivity(new Intent(MainActivity.this, SecondActivity.class));
}

Другий вид діяльності:

public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setTheme(android.R.style.Theme);
    setContentView(R.layout.activity_second);
}

Уривок маніфесту:

 <activity android:name="SecondActivity" android:theme="@android:style/Theme.Dialog"></activity>

Коли я запускаю, це все ще є тематичним діалогом.

API10

Дякую.

Відповіді:


184

Як кажуть документи , вам потрібно зателефонувати setThemeперед будь-яким результатом перегляду. Здається, super.onCreate()бере участь в viewобробці.

Отже, щоб динамічно переходити між темами, вам просто потрібно зателефонувати setThemeперед super.onCreateцим:

public void onCreate(Bundle savedInstanceState) {
    setTheme(android.R.style.Theme);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
}

Для мене працює MotoG (v1) зі стеком Android 5.1. Якщо це не працює, поділіться пристроєм та версією Android.
lenrok258

Я повинен був визначити тему, як описано тут: stackoverflow.com/a/44236460/3211335 А потім встановити її так, як описано у цій відповіді. Це чудово працює.
LaloLoop

Чи все-таки ми можемо задати тему лише один раз ... замість заданої теми на сторінку
gayan1991

Я використовую спільну перевагу для збереження теми, але при перезапуску програми на мить з’являється перша тема, а потім показана друга!
Мохаммед Афраштех

1
@ gayan1991 Ви можете скористатися іншою діяльністю, щоб визначити свою тему та змусити всі ваші інші дії розширити цю, наприклад: pastebin.com/r93qrRDG редагувати: використовуйте pastebin для кращого форматування
SocialSupaCrew

46

відповідь користувача1462299 чудово працює, але якщо ви включите фрагменти , вони використовуватимуть оригінальну тему діяльності. Щоб застосувати тему також до всіх фрагментів, ви можете замінити метод контексту getTheme () :

@Override
public Resources.Theme getTheme() {
    Resources.Theme theme = super.getTheme();
    if(useAlternativeTheme){
        theme.applyStyle(R.style.AlternativeTheme, true);
    }
    // you could also use a switch if you have many themes that could apply
    return theme;
}

Вам більше не потрібно викликати setTheme () у методі onCreate (). Ви переосмислюєте кожен запит, щоб отримати поточну тему в цьому контексті таким чином.


2
@ хто хто виступав проти: будь ласка, поясніть, що вам не подобається у моїй відповіді?
Björn Kechel

Чи слід перекрити getTheme () у діяльності чи у відповідних фрагментах? Я реалізував це в діяльності, але Фрагменти все ще використовують оригінальну тему діяльності.
сальтандпеппер

@saltandpepper Перевизначення його в діяльності досить. Переконайтеся, що код вашого фрагмента та макет не змінюють його знову.
Бьорн Кехель

Це не спрацювало для мене, але відповідь, надана в stackoverflow.com/a/15496425/494179, зробила це.
сальтандпеппер

2
Хороший пункт користувача1269737, тому ви повинні переконатися, що немає важкого розрахунку. Просто повернення стилю в простому випадку не вплине на продуктивність.
Бьорн Кечел

12

Я знаю, що я спізнююсь, але я хотів би опублікувати рішення тут:
Перевірте повний вихідний код тут .
Це код, який я використовував при зміні теми за допомогою налаштувань ..

SharedPreferences pref = PreferenceManager
        .getDefaultSharedPreferences(this);
String themeName = pref.getString("prefSyncFrequency3", "Theme1");
if (themeName.equals("Africa")) {
    setTheme(R.style.AppTheme);



} else if (themeName.equals("Colorful Beach")) {
    //Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
    setTheme(R.style.beach);


} else if (themeName.equals("Abstract")) {
    //Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();

    setTheme(R.style.abstract2);

} else if (themeName.equals("Default")) {

    setTheme(R.style.defaulttheme);

}

Зверніть увагу, що ви повинні поставити код перед setcontentview ..

ЩАСЛОВА КОДУВАННЯ!


чому? відповідь є коректною ?!
dondondon

Я використовую спільну перевагу для збереження теми, але при перезапуску програми на мить з’являється перша тема, а потім показана друга!
Мохаммед Афраштех

0

Цей для мене чудово працює:

theme.applyStyle(R.style.AppTheme, true)

Використання:

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    //The call goes right after super.onCreate() and before setContentView()
    theme.applyStyle(R.style.AppTheme, true)
    setContentView(layoutId)
    onViewCreated(savedInstanceState)
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.