Use fragment for keyboard theme settings

Bug: 11866784
Change-Id: Ic50b6eb1bd8f2b823e2c9dfad04d8615bc910936
diff --git a/java/res/layout/radio_button_preference_widget.xml b/java/res/layout/radio_button_preference_widget.xml
new file mode 100644
index 0000000..ee9cda1
--- /dev/null
+++ b/java/res/layout/radio_button_preference_widget.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RadioButton
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/radio_button"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:clickable="false"
+    android:focusable="false" />
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 66091a0..ba285de 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -22,12 +22,10 @@
         android:fragment="com.android.inputmethod.latin.settings.InputSettingsFragment"
         android:title="@string/settings_screen_input"
         android:key="screen_input" />
-    <ListPreference
-        android:key="pref_keyboard_theme"
+    <PreferenceScreen
+        android:fragment="com.android.inputmethod.latin.settings.ThemeSettingsFragment"
         android:title="@string/keyboard_theme"
-        android:entryValues="@array/keyboard_theme_ids"
-        android:entries="@array/keyboard_theme_names"
-        android:persistent="true" />
+        android:key="screen_theme" />
     <PreferenceScreen
         android:fragment="com.android.inputmethod.latin.settings.MultiLingualSettingsFragment"
         android:title="@string/settings_screen_multi_lingual"
diff --git a/java/res/xml/prefs_screen_theme.xml b/java/res/xml/prefs_screen_theme.xml
new file mode 100644
index 0000000..b49f0be
--- /dev/null
+++ b/java/res/xml/prefs_screen_theme.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+    android:title="@string/keyboard_theme"
+    android:key="screen_theme">
+    <!-- Keyboard theme list will be populated programmatically here. -->
+</PreferenceScreen>
diff --git a/java/src/com/android/inputmethod/latin/settings/GestureSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/GestureSettingsFragment.java
index b95c356..832fbf6 100644
--- a/java/src/com/android/inputmethod/latin/settings/GestureSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/GestureSettingsFragment.java
@@ -36,9 +36,4 @@
         super.onCreate(icicle);
         addPreferencesFromResource(R.xml.prefs_screen_gesture);
     }
-
-    @Override
-    public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
-        // Nothing to do here.
-    }
 }
diff --git a/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java
index f40106b..fcdd393 100644
--- a/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java
@@ -63,11 +63,6 @@
         updateCustomInputStylesSummary();
     }
 
-    @Override
-    public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
-        // Nothing to do here.
-    }
-
     private void updateCustomInputStylesSummary() {
         final SharedPreferences prefs = getSharedPreferences();
         final Resources res = getResources();
diff --git a/java/src/com/android/inputmethod/latin/settings/RadioButtonPreference.java b/java/src/com/android/inputmethod/latin/settings/RadioButtonPreference.java
new file mode 100644
index 0000000..c173d47
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/RadioButtonPreference.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.settings;
+
+import android.content.Context;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.RadioButton;
+
+import com.android.inputmethod.latin.R;
+
+/**
+ * Radio Button preference
+ */
+public class RadioButtonPreference extends Preference {
+    interface OnRadioButtonClickedListener {
+        /**
+         * Called when this preference needs to be saved its state.
+         *
+         * @param preference This preference.
+         */
+        public void onRadioButtonClicked(RadioButtonPreference preference);
+    }
+
+    private boolean mIsSelected;
+    private RadioButton mRadioButton;
+    private OnRadioButtonClickedListener mListener;
+    private final View.OnClickListener mClickListener = new View.OnClickListener() {
+        @Override
+        public void onClick(final View v) {
+            if (mListener != null) {
+                mListener.onRadioButtonClicked(RadioButtonPreference.this);
+            }
+        }
+    };
+
+    public RadioButtonPreference(final Context context) {
+        this(context, null);
+    }
+
+    public RadioButtonPreference(final Context context, final AttributeSet attrs) {
+        this(context, attrs, android.R.attr.preferenceStyle);
+    }
+
+    public RadioButtonPreference(final Context context, final AttributeSet attrs,
+            final int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        setWidgetLayoutResource(R.layout.radio_button_preference_widget);
+    }
+
+    public void setOnRadioButtonClickedListener(final OnRadioButtonClickedListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    protected void onBindView(final View view) {
+        super.onBindView(view);
+        mRadioButton = (RadioButton)view.findViewById(R.id.radio_button);
+        mRadioButton.setChecked(mIsSelected);
+        mRadioButton.setOnClickListener(mClickListener);
+        view.setOnClickListener(mClickListener);
+    }
+
+    public boolean isSelected() {
+        return mIsSelected;
+    }
+
+    public void setSelected(final boolean selected) {
+        if (selected == mIsSelected) {
+            return;
+        }
+        mIsSelected = selected;
+        if (mRadioButton != null) {
+            mRadioButton.setChecked(selected);
+        }
+        notifyChanged();
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 0e6a15a..90174e4 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -41,6 +41,7 @@
     private static final String TAG = Settings.class.getSimpleName();
     // Settings screens
     public static final String SCREEN_INPUT = "screen_input";
+    public static final String SCREEN_THEME = "screen_theme";
     public static final String SCREEN_MULTI_LINGUAL = "screen_multi_lingual";
     public static final String SCREEN_GESTURE = "screen_gesture";
     public static final String SCREEN_CORRECTION = "screen_correction";
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index 9364520..6734a9c 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -16,47 +16,23 @@
 
 package com.android.inputmethod.latin.settings;
 
-import android.app.Activity;
-import android.app.backup.BackupManager;
-import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
 import android.os.Bundle;
-import android.preference.ListPreference;
 import android.preference.PreferenceScreen;
-import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 
-import com.android.inputmethod.keyboard.KeyboardTheme;
-import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.utils.ApplicationUtils;
 import com.android.inputmethod.latin.utils.FeedbackUtils;
 import com.android.inputmethodcommon.InputMethodSettingsFragment;
 
-public final class SettingsFragment extends InputMethodSettingsFragment
-        implements SharedPreferences.OnSharedPreferenceChangeListener {
-    private static final String TAG = SettingsFragment.class.getSimpleName();
-
+public final class SettingsFragment extends InputMethodSettingsFragment {
     private static final int NO_MENU_GROUP = Menu.NONE; // We don't care about menu grouping.
     private static final int MENU_FEEDBACK = Menu.FIRST; // The first menu item id and order.
     private static final int MENU_ABOUT = Menu.FIRST + 1; // The second menu item id and order.
 
-    private void updateListPreferenceSummaryToCurrentValue(final String prefKey) {
-        // Because the "%s" summary trick of {@link ListPreference} doesn't work properly before
-        // KitKat, we need to update the summary programmatically.
-        final ListPreference listPreference = (ListPreference)findPreference(prefKey);
-        if (listPreference == null) {
-            return;
-        }
-        final CharSequence entries[] = listPreference.getEntries();
-        final int entryIndex = listPreference.findIndexOfValue(listPreference.getValue());
-        listPreference.setSummary(entryIndex < 0 ? null : entries[entryIndex]);
-    }
-
     @Override
     public void onCreate(final Bundle icicle) {
         super.onCreate(icicle);
@@ -65,73 +41,14 @@
         setSubtypeEnablerTitle(R.string.select_language);
         addPreferencesFromResource(R.xml.prefs);
         final PreferenceScreen preferenceScreen = getPreferenceScreen();
-        TwoStatePreferenceHelper.replaceCheckBoxPreferencesBySwitchPreferences(preferenceScreen);
         preferenceScreen.setTitle(
                 ApplicationUtils.getActivityTitleResId(getActivity(), SettingsActivity.class));
-
-        final Resources res = getResources();
-        final Context context = getActivity();
-
-        // When we are called from the Settings application but we are not already running, some
-        // singleton and utility classes may not have been initialized.  We have to call
-        // initialization method of these classes here. See {@link LatinIME#onCreate()}.
-        AudioAndHapticFeedbackManager.init(context);
-
-        final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
-        prefs.registerOnSharedPreferenceChangeListener(this);
-
-        if (!Settings.readFromBuildConfigIfGestureInputEnabled(res)) {
-            getPreferenceScreen().removePreference(findPreference(Settings.SCREEN_GESTURE));
-        }
-
-        AdditionalFeaturesSettingUtils.addAdditionalFeaturesPreferences(context, this);
     }
 
     @Override
     public void onResume() {
         super.onResume();
-        final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
-        final ListPreference keyboardThemePref = (ListPreference)findPreference(
-                Settings.PREF_KEYBOARD_THEME);
-        if (keyboardThemePref != null) {
-            final KeyboardTheme keyboardTheme = KeyboardTheme.getKeyboardTheme(prefs);
-            final String value = Integer.toString(keyboardTheme.mThemeId);
-            final CharSequence entries[] = keyboardThemePref.getEntries();
-            final int entryIndex = keyboardThemePref.findIndexOfValue(value);
-            keyboardThemePref.setSummary(entryIndex < 0 ? null : entries[entryIndex]);
-            keyboardThemePref.setValue(value);
-        }
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
-        final ListPreference keyboardThemePref = (ListPreference)findPreference(
-                Settings.PREF_KEYBOARD_THEME);
-        if (keyboardThemePref != null) {
-            KeyboardTheme.saveKeyboardThemeId(keyboardThemePref.getValue(), prefs);
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
-                this);
-        super.onDestroy();
-    }
-
-    @Override
-    public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
-        final Activity activity = getActivity();
-        if (activity == null) {
-            // TODO: Introduce a static function to register this class and ensure that
-            // onCreate must be called before "onSharedPreferenceChanged" is called.
-            Log.w(TAG, "onSharedPreferenceChanged called before activity starts.");
-            return;
-        }
-        (new BackupManager(activity)).dataChanged();
-        updateListPreferenceSummaryToCurrentValue(Settings.PREF_KEYBOARD_THEME);
+        ThemeSettingsFragment.updateKeyboardThemeSummary(findPreference(Settings.SCREEN_THEME));
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java b/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java
index c70bf29..ca5b395 100644
--- a/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java
@@ -115,4 +115,9 @@
                 mSharedPreferenceChangeListener);
         super.onDestroy();
     }
+
+    @Override
+    public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
+        // This method may be overridden by an extended class.
+    }
 }
diff --git a/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java
new file mode 100644
index 0000000..5a3fc36
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.settings;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+
+import com.android.inputmethod.keyboard.KeyboardTheme;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.settings.RadioButtonPreference.OnRadioButtonClickedListener;
+
+/**
+ * "Keyboard theme" settings sub screen.
+ */
+public final class ThemeSettingsFragment extends SubScreenFragment
+        implements OnRadioButtonClickedListener {
+    private String mSelectedThemeId;
+
+    static class KeyboardThemePreference extends RadioButtonPreference {
+        final String mThemeId;
+
+        KeyboardThemePreference(final Context context, final String name, final String id) {
+            super(context);
+            setTitle(name);
+            mThemeId = id;
+        }
+    }
+
+    static void updateKeyboardThemeSummary(final Preference pref) {
+        final Resources res = pref.getContext().getResources();
+        final SharedPreferences prefs = pref.getSharedPreferences();
+        final KeyboardTheme keyboardTheme = KeyboardTheme.getKeyboardTheme(prefs);
+        final String keyboardThemeId = String.valueOf(keyboardTheme.mThemeId);
+        final String[] keyboardThemeNames = res.getStringArray(R.array.keyboard_theme_names);
+        final String[] keyboardThemeIds = res.getStringArray(R.array.keyboard_theme_ids);
+        for (int index = 0; index < keyboardThemeNames.length; index++) {
+            if (keyboardThemeId.equals(keyboardThemeIds[index])) {
+                pref.setSummary(keyboardThemeNames[index]);
+                return;
+            }
+        }
+    }
+
+    @Override
+    public void onCreate(final Bundle icicle) {
+        super.onCreate(icicle);
+        addPreferencesFromResource(R.xml.prefs_screen_theme);
+        final PreferenceScreen screen = getPreferenceScreen();
+        final Resources res = getResources();
+        final String[] keyboardThemeNames = res.getStringArray(R.array.keyboard_theme_names);
+        final String[] keyboardThemeIds = res.getStringArray(R.array.keyboard_theme_ids);
+        for (int index = 0; index < keyboardThemeNames.length; index++) {
+            final KeyboardThemePreference pref = new KeyboardThemePreference(
+                    getActivity(), keyboardThemeNames[index], keyboardThemeIds[index]);
+            screen.addPreference(pref);
+            pref.setOnRadioButtonClickedListener(this);
+        }
+        final SharedPreferences prefs = getSharedPreferences();
+        final KeyboardTheme keyboardTheme = KeyboardTheme.getKeyboardTheme(prefs);
+        mSelectedThemeId = String.valueOf(keyboardTheme.mThemeId);
+    }
+
+    @Override
+    public void onRadioButtonClicked(final RadioButtonPreference preference) {
+        if (preference instanceof KeyboardThemePreference) {
+            final KeyboardThemePreference pref = (KeyboardThemePreference)preference;
+            mSelectedThemeId = pref.mThemeId;
+            updateSelected();
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        updateSelected();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        KeyboardTheme.saveKeyboardThemeId(mSelectedThemeId, getSharedPreferences());
+    }
+
+    private void updateSelected() {
+        final PreferenceScreen screen = getPreferenceScreen();
+        final int count = screen.getPreferenceCount();
+        for (int index = 0; index < count; index++) {
+            final Preference preference = screen.getPreference(index);
+            if (preference instanceof KeyboardThemePreference) {
+                final KeyboardThemePreference pref = (KeyboardThemePreference)preference;
+                final boolean selected = mSelectedThemeId.equals(pref.mThemeId);
+                pref.setSelected(selected);
+            }
+        }
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
index 9858a23..08f5b0b 100644
--- a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
@@ -26,6 +26,7 @@
 import com.android.inputmethod.latin.settings.InputSettingsFragment;
 import com.android.inputmethod.latin.settings.MultiLingualSettingsFragment;
 import com.android.inputmethod.latin.settings.SettingsFragment;
+import com.android.inputmethod.latin.settings.ThemeSettingsFragment;
 import com.android.inputmethod.latin.spellcheck.SpellCheckerSettingsFragment;
 import com.android.inputmethod.latin.userdictionary.UserDictionaryAddWordFragment;
 import com.android.inputmethod.latin.userdictionary.UserDictionaryList;
@@ -40,6 +41,7 @@
         sLatinImeFragments.add(DictionarySettingsFragment.class.getName());
         sLatinImeFragments.add(AboutPreferences.class.getName());
         sLatinImeFragments.add(InputSettingsFragment.class.getName());
+        sLatinImeFragments.add(ThemeSettingsFragment.class.getName());
         sLatinImeFragments.add(MultiLingualSettingsFragment.class.getName());
         sLatinImeFragments.add(CustomInputStyleSettingsFragment.class.getName());
         sLatinImeFragments.add(GestureSettingsFragment.class.getName());