2016-06-14 1 views
0

У меня есть приложение, в котором пользователь может выбирать между несколькими разными цветными темами от PreferenceActivity и тем самым изменять тему/цвет всего приложения. Но изменения, выбранные в PreferenceActivity, не применяются немедленно. Изменения применяются только тогда, когда пользователь ретенторPreferenceActivity.Как применить тему/стиль в андроиде без перезапуска?

Я знаю, что могу называть recreate() каждый раз, когда выбирается тема, но я хочу знать, существует ли лучшее решение без воссоздания всей активности.

Вот видео о том, как он в настоящее время работает:https://www.youtube.com/watch?v=oU8xIUi_48A

Это где я установил выбранное значение из preferenceList в моем PreferenceActivity:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    setTheme(); 
    themecolorList.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 
     @Override 
     public boolean onPreferenceChange(Preference preference, Object newValue) { 
      switch (themecolorList.getValue()) { 

       case "grey": 
        themecolorList.getEditor().putString("grey", "green").apply(); 
        break; 
       case "green": 
        themecolorList.getEditor().putString("green", "green").apply(); 
        setTheme(R.style.AppTheme_default); 
        break; 
       case "blue": 
        themecolorList.getEditor().putString("blue", "green").apply(); 
        break; 
       case "yellow": 
        themecolorList.getEditor().putString("yellow", "green").apply(); 
        break; 
       case "red": 
        themecolorList.getEditor().putString("red", "green").apply(); 
        break; 
       case "pink": 
        themecolorList.getEditor().putString("pink", "green").apply(); 
        break; 

       default: 
        themecolorList.getEditor().putString("green", "green").apply(); 
        break; 
      } 

      recreate(); 
      return true; 


     } 
    }); 
    } 

Метод setTheme(); называется в моем PreferenceActivitys onCreate(); метод

private void setTheme() { 

    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); 
    switch (sharedPreferences.getString("THEME_KEY", "green")) { 

     case "grey": 
      setTheme(R.style.AppTheme_Grey); 
      break; 

     case "green": 
      setTheme(R.style.AppTheme_default); 
      break; 

     case "blue": 
      setTheme(R.style.AppTheme_Blue); 
      break; 

     case "yellow": 
      setTheme(R.style.AppTheme_Yellow); 
      break; 

     case "red": 
      setTheme(R.style.AppTheme_Red); 
      break; 

     case "pink": 
      setTheme(R.style.AppTheme_Pink); 
      break; 

     default: 
      getApplication().setTheme(R.style.AppTheme_default); 
      setTheme(R.style.AppTheme_default); 
      break; 
    } 
} 

ответ

3

Похоже, что лучшим решением является использование recreate(); так как нет другого способа обновить весь макет для деятельности:

Для Каждый раз, когда пользователь нажимает на величинуХ опций из списка тем ключ/значение для прессованного одного сохраненного с помощью OnPreferenceChangeListener в SharedPreference и recreate(); затем вызывается.

themecolorList.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 
     @Override 
     public boolean onPreferenceChange(Preference preference, Object newValue) { 
      recreate(); 
      return true; 
     } 
    }); 

В моей PreferenceActivity s onCreate(); я называю выполненный на заказ метод setTheme(); который вызывается после того, как recreate(); называется. setTheme(); просто смотрит на то, что сохраняется в SharedPreference от OnPreferenceChangeListener и установить тему на соответствующее значение

@Override 
public void onCreate(Bundle savedInstanceState) { 
    setTheme(); 
    super.onCreate(savedInstanceState); 
} 
0

Вы не можете. Вы можете начать новое действие для выбора темы и когда пользователь выбирает завершение этой активности.

+0

Использование 'заново();' будет лучший вариант, то, чем начать новое намерение для каждый раз пользователь нажимает по выбору в списке предпочтений – Muddz

0

Запуск обновления макета (путем поворота устройства или приведения приложения в состояние поворота), как правило, приводит к перезагрузке его ресурсов.

Я точно не помню, как это сделать в данный момент, но это была обычная практика в последний раз, когда я исследовал, как сделать что-то подобное. Не забудьте указать (в манифесте?), Что ваша деятельность будет обрабатывать изменения макета/поворот экрана, чтобы избежать полного перезапуска (и потери каких-либо несохраненных данных).

+0

Звучит как классное решение.Единственный улов в том, что я сделал свое приложение работать только в режиме potrait, так как его использование в ландшафтном режиме нецелесообразно. – Muddz

+0

Ха-ха, у меня была такая же проблема, как и вы! : p (http://stackoverflow.com/questions/11705963/forcing-a-different-locale-works-only-for-top-activity-in-back-stack/11710007#comment15537029_11710007). Но тогда я думаю, что вы застряли в воссоздании активности, или вы можете сделать предварительный просмотр (всплывающее изображение или применить цвета стиля к элементу списка, если это возможно?), А затем просто воссоздать действие (используя Bundle для подачи текущее состояние нового экземпляра, если необходимо), когда пользователь делает выбор. – ToVine

0

Похоже, существует метод, называемый invalidate(), который должен быть вызван для представлений, которые необходимо перерисовать.

Link

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

+0

В 'PreferenceActivity' или' AppCompatPreferenceActivity' есть только такие: 'invalidateOptionsMenu();' invalidateHeaders(); 'и ни одна из этих работ – Muddz

+0

О, я понимаю, извините. – Buildersrejected

Смежные вопросы