3

PreferenceFragmentユーザーがテーマを選択できるようにする設定があります。ユーザーは、暗いテーマまたは明るいテーマを選択できます。テーマを選択した後、ユーザーは戻るボタンを押して前のフラグメントに戻ります。これにより、テーマが読み取られて適用される、含まれているアクティビティの onCreate メソッドが呼び出されます。ただし、テーマが正しく適用されていません。Holo.Light から Holo.Dark に切り替えると、背景色、アクション バーなどが変更されますが、テキストは変更されず、テキストが色あせて読みにくくなります。私が間違っていることはありますか?私が読んだことはすべて、テーマを onCreate メソッドに適用する必要があると述べており、それが私がやっていることです。

よろしくお願いします。

編集

ここで要求されたのは、関連するコードです。

public class MainActivity extends Activity {

     private ActionBarDrawerToggle mSlideMenuToggle;
     private boolean isDarkTheme;
     private static final String InitializedKey = "initialized";

     @Override
 protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
          applySettings();
          setContentView(R.layout.activity_main);
       }

     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
          if (mSlideMenuToggle.onOptionsItemSelected(item)) {
               return true;
          } else if (item.getItemId() == R.id.menu_settings) {
               getFragmentManager().beginTransaction()
                        .replace(R.id.content_frame, new SettingsFragment())
                        .addToBackStack(null)
                        .commit();
               return true;
          } else {
               return super.onOptionsItemSelected(item);
          }
     }

     private void applySettings() {
          isDarkTheme = PreferenceManager.getDefaultSharedPreferences(this).getString(SettingsFragment.ThemeSetting, null).equals("1");
          if (isDarkTheme) {
               setTheme(android.R.style.Theme_Holo);
          } else {
               setTheme(android.R.style.Theme_Holo_Light);
     }
}

このonCreateメソッドは、 を呼び出して現在のテーマをアクティビティに適用しapplySettingsます。オプション メニューを使用すると、SettingsFragmentを作成できます。

public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {

   public static final String ThemeSetting = "isDarkTheme";

   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       addPreferencesFromResource(R.xml.preferences);
   }

   @Override
   public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
       if (key.equals(ThemeSetting)) {
           String[] themes = getResources().getStringArray(R.array.isDarkThemeStrings);
           findPreference(key).setSummary(sharedPreferences.getString(key, "").equals("0") ? themes[0] : themes[1]);
       }
   }

   @Override
   public void onResume() {
       super.onResume();
       PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(this);
   }

   @Override
   public void onPause() {
       super.onPause();
       PreferenceManager.getDefaultSharedPreferences(getActivity()).unregisterOnSharedPreferenceChangeListener(this);
   }

 }

SettingsFragmentは 1 つの設定、Theme があり、Dark または Light の 2 つの値のいずれかを持つことができます。ユーザーはいずれかを選択し、戻るボタンを押します。これにより、 のonCreateメソッドMainActivityが呼び出され、設定が再度適用されますが、正しくは適用されません。

誰?でテーマを変更してSettingsFragmentから戻るボタンを押すと、テーマが適用されるはずですMainActivityが、そうではありません。ほとんどの要素は変更されますが、テキストは暗いままです (Holo.Light から Holo.Dark に変わります)。

4

3 に答える 3

0

ここでの問題は、アクティビティを再作成しない限り、テーマが適用されないことです。テーマは、onCreate() で setContentView メソッドを呼び出す前にアクティビティに適用されます。戻るときは、onCreate() メソッドではなく、onResume() を介して再入力します。

この問題を回避するには、テーマの設定を変更すると、バック スタックをクリアする必要があります。そうしないと、バック スタックのアクティビティにテーマが適用されません。ユーザビリティの観点から、この種の設定はアプリのトップレベルのアクティビティを通じてのみ利用可能であるべきです。

ThemeChangeListener を実装してアクティビティに追加します。テーマが変更されたら、ThemeChangeListener を呼び出し、開いているアクティビティ (現在のページを除く) で finish() を呼び出します。次に onBack() で、リサが提供したコードを使用して、ユーザーが設定ページにナビゲートしたトップ レベルのアクティビティを手動で再作成します。

インテント エクストラ/データを使用して、以前に入力されたデータを使用して親アクティビティを再作成することを管理できます。

于 2013-07-25T09:14:03.573 に答える