diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 7e4c28496..749551c2a 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -19,41 +19,9 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     android:key="english_ime_settings">
     <PreferenceScreen
+        android:fragment="com.android.inputmethod.latin.settings.InputSettingsFragment"
         android:title="@string/settings_screen_input"
-        android:key="screen_input">
-        <CheckBoxPreference
-            android:key="auto_cap"
-            android:title="@string/auto_cap"
-            android:summary="@string/auto_cap_summary"
-            android:defaultValue="true"
-            android:persistent="true" />
-        <CheckBoxPreference
-            android:key="pref_key_use_double_space_period"
-            android:title="@string/use_double_space_period"
-            android:summary="@string/use_double_space_period_summary"
-            android:defaultValue="true"
-            android:persistent="true" />
-        <CheckBoxPreference
-            android:key="vibrate_on"
-            android:title="@string/vibrate_on_keypress"
-            android:defaultValue="@bool/config_default_vibration_enabled"
-            android:persistent="true" />
-        <CheckBoxPreference
-            android:key="sound_on"
-            android:title="@string/sound_on_keypress"
-            android:defaultValue="@bool/config_default_sound_enabled"
-            android:persistent="true" />
-        <CheckBoxPreference
-            android:key="popup_on"
-            android:title="@string/popup_on_keypress"
-            android:defaultValue="@bool/config_default_key_preview_popup"
-            android:persistent="true" />
-        <CheckBoxPreference
-            android:key="pref_voice_input_key"
-            android:title="@string/voice_input"
-            android:defaultValue="true"
-            android:persistent="true" />
-    </PreferenceScreen>
+        android:key="screen_input" />
     <ListPreference
         android:key="pref_keyboard_theme"
         android:title="@string/keyboard_theme"
diff --git a/java/res/xml/prefs_screen_input.xml b/java/res/xml/prefs_screen_input.xml
new file mode 100644
index 000000000..7704e3f80
--- /dev/null
+++ b/java/res/xml/prefs_screen_input.xml
@@ -0,0 +1,53 @@
+<?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/settings_screen_input">
+    <CheckBoxPreference
+        android:key="auto_cap"
+        android:title="@string/auto_cap"
+        android:summary="@string/auto_cap_summary"
+        android:defaultValue="true"
+        android:persistent="true" />
+    <CheckBoxPreference
+        android:key="pref_key_use_double_space_period"
+        android:title="@string/use_double_space_period"
+        android:summary="@string/use_double_space_period_summary"
+        android:defaultValue="true"
+        android:persistent="true" />
+    <CheckBoxPreference
+        android:key="vibrate_on"
+        android:title="@string/vibrate_on_keypress"
+        android:defaultValue="@bool/config_default_vibration_enabled"
+        android:persistent="true" />
+    <CheckBoxPreference
+        android:key="sound_on"
+        android:title="@string/sound_on_keypress"
+        android:defaultValue="@bool/config_default_sound_enabled"
+        android:persistent="true" />
+    <CheckBoxPreference
+        android:key="popup_on"
+        android:title="@string/popup_on_keypress"
+        android:defaultValue="@bool/config_default_key_preview_popup"
+        android:persistent="true" />
+    <CheckBoxPreference
+        android:key="pref_voice_input_key"
+        android:title="@string/voice_input"
+        android:defaultValue="true"
+        android:persistent="true" />
+</PreferenceScreen>
diff --git a/java/src/com/android/inputmethod/latin/settings/InputSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/InputSettingsFragment.java
new file mode 100644
index 000000000..f459d68dd
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/InputSettingsFragment.java
@@ -0,0 +1,100 @@
+/*
+ * 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 com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+
+/**
+ * "Input preferences" settings sub screen.
+ *
+ * This settings sub screen handles the following input preferences.
+ * - Auto-capitalization
+ * - Double-space period
+ * - Vibrate on keypress
+ * - Sound on keypress
+ * - Popup on keypress
+ * - Voice input key
+ */
+public final class InputSettingsFragment extends SubScreenFragment {
+    @Override
+    public void onCreate(final Bundle icicle) {
+        super.onCreate(icicle);
+        addPreferencesFromResource(R.xml.prefs_screen_input);
+
+        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()}.
+        SubtypeSwitcher.init(context);
+
+        final boolean showVoiceKeyOption = res.getBoolean(
+                R.bool.config_enable_show_voice_key_option);
+        if (!showVoiceKeyOption) {
+            removePreference(Settings.PREF_VOICE_INPUT_KEY);
+        }
+        if (!AudioAndHapticFeedbackManager.getInstance().hasVibrator()) {
+            removePreference(Settings.PREF_VIBRATE_ON);
+        }
+        if (!Settings.readFromBuildConfigIfToShowKeyPreviewPopupOption(res)) {
+            removePreference(Settings.PREF_POPUP_ON);
+        }
+
+        refreshEnablingsOfKeypressSoundAndVibrationSettings();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        final Preference voiceInputKeyOption = findPreference(Settings.PREF_VOICE_INPUT_KEY);
+        if (voiceInputKeyOption != null) {
+            final boolean isShortcutImeEnabled = SubtypeSwitcher.getInstance()
+                    .isShortcutImeEnabled();
+            voiceInputKeyOption.setEnabled(isShortcutImeEnabled);
+            voiceInputKeyOption.setSummary(
+                    isShortcutImeEnabled ? null : getText(R.string.voice_input_disabled_summary));
+        }
+    }
+
+    @Override
+    public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
+        final Resources res = getResources();
+        if (key.equals(Settings.PREF_POPUP_ON)) {
+            setPreferenceEnabled(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
+                    Settings.readKeyPreviewPopupEnabled(prefs, res));
+        }
+        refreshEnablingsOfKeypressSoundAndVibrationSettings();
+    }
+
+    private void refreshEnablingsOfKeypressSoundAndVibrationSettings() {
+        final SharedPreferences prefs = getSharedPreferences();
+        final Resources res = getResources();
+        setPreferenceEnabled(Settings.PREF_VIBRATION_DURATION_SETTINGS,
+                Settings.readVibrationEnabled(prefs, res));
+        setPreferenceEnabled(Settings.PREF_KEYPRESS_SOUND_VOLUME,
+                Settings.readKeypressSoundEnabled(prefs, res));
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java b/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
index c899507e3..c7b9dcdd9 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
@@ -35,8 +35,7 @@ public final class SettingsActivity extends PreferenceActivity {
         return intent;
     }
 
-    // TODO: Uncomment the override annotation once we start using SDK version 19.
-    // @Override
+    @Override
     public boolean isValidFragment(String fragmentName) {
         return FragmentUtils.isValidFragment(fragmentName);
     }
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index b289174c6..ec842eff2 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -42,7 +42,6 @@ import com.android.inputmethod.dictionarypack.DictionarySettingsActivity;
 import com.android.inputmethod.keyboard.KeyboardTheme;
 import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeSwitcher;
 import com.android.inputmethod.latin.define.ProductionFlags;
 import com.android.inputmethod.latin.setup.LauncherIconVisibilityManager;
 import com.android.inputmethod.latin.userdictionary.UserDictionaryList;
@@ -114,7 +113,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment
         // 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()}.
-        SubtypeSwitcher.init(context);
         SubtypeLocaleUtils.init(context);
         AudioAndHapticFeedbackManager.init(context);
 
@@ -123,8 +121,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment
 
         ensureConsistencyOfAutoCorrectionSettings();
 
-        final PreferenceScreen inputScreen =
-                (PreferenceScreen) findPreference(Settings.SCREEN_INPUT);
         final PreferenceScreen multiLingualScreen =
                 (PreferenceScreen) findPreference(Settings.SCREEN_MULTI_LINGUAL);
         final PreferenceScreen gestureScreen =
@@ -140,14 +136,7 @@ public final class SettingsFragment extends InputMethodSettingsFragment
             advancedScreen.removePreference(debugScreen);
         }
 
-        final boolean showVoiceKeyOption = res.getBoolean(
-                R.bool.config_enable_show_voice_key_option);
-        if (!showVoiceKeyOption) {
-            removePreference(Settings.PREF_VOICE_INPUT_KEY, inputScreen);
-        }
-
         if (!AudioAndHapticFeedbackManager.getInstance().hasVibrator()) {
-            removePreference(Settings.PREF_VIBRATE_ON, inputScreen);
             removePreference(Settings.PREF_VIBRATION_DURATION_SETTINGS, advancedScreen);
         }
         if (!Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS) {
@@ -158,7 +147,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment
 
         // TODO: consolidate key preview dismiss delay with the key preview animation parameters.
         if (!Settings.readFromBuildConfigIfToShowKeyPreviewPopupOption(res)) {
-            removePreference(Settings.PREF_POPUP_ON, inputScreen);
             removePreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, advancedScreen);
         } else {
             // TODO: Cleanup this setup.
@@ -234,14 +222,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment
         super.onResume();
         final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
         final Resources res = getResources();
-        final Preference voiceInputKeyOption = findPreference(Settings.PREF_VOICE_INPUT_KEY);
-        if (voiceInputKeyOption != null) {
-            final boolean isShortcutImeEnabled = SubtypeSwitcher.getInstance()
-                    .isShortcutImeEnabled();
-            voiceInputKeyOption.setEnabled(isShortcutImeEnabled);
-            voiceInputKeyOption.setSummary(isShortcutImeEnabled ? null
-                    : res.getText(R.string.voice_input_disabled_summary));
-        }
         final TwoStatePreference showSetupWizardIcon =
                 (TwoStatePreference)findPreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON);
         if (showSetupWizardIcon != null) {
diff --git a/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java b/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java
new file mode 100644
index 000000000..c70bf2997
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java
@@ -0,0 +1,118 @@
+/*
+ * 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.app.backup.BackupManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.util.Log;
+
+/**
+ * A base abstract class for a {@link PreferenceFragment} that implements a nested
+ * {@link PreferenceScreen} of the main preference screen.
+ */
+abstract class SubScreenFragment extends PreferenceFragment
+        implements OnSharedPreferenceChangeListener {
+    private OnSharedPreferenceChangeListener mSharedPreferenceChangeListener;
+
+    static void setPreferenceEnabled(final String prefKey, final boolean enabled,
+            final PreferenceScreen screen) {
+        final Preference preference = screen.findPreference(prefKey);
+        if (preference != null) {
+            preference.setEnabled(enabled);
+        }
+    }
+
+    static void removePreference(final String prefKey, final PreferenceScreen screen) {
+        final Preference preference = screen.findPreference(prefKey);
+        if (preference != null) {
+            screen.removePreference(preference);
+        }
+    }
+
+    static void updateListPreferenceSummaryToCurrentValue(final String prefKey,
+            final PreferenceScreen screen) {
+        // 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)screen.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]);
+    }
+
+    final void setPreferenceEnabled(final String prefKey, final boolean enabled) {
+        setPreferenceEnabled(prefKey, enabled, getPreferenceScreen());
+    }
+
+    final void removePreference(final String prefKey) {
+        removePreference(prefKey, getPreferenceScreen());
+    }
+
+    final void updateListPreferenceSummaryToCurrentValue(final String prefKey) {
+        updateListPreferenceSummaryToCurrentValue(prefKey, getPreferenceScreen());
+    }
+
+    final SharedPreferences getSharedPreferences() {
+        return getPreferenceManager().getSharedPreferences();
+    }
+
+    @Override
+    public void addPreferencesFromResource(final int preferencesResId) {
+        super.addPreferencesFromResource(preferencesResId);
+        TwoStatePreferenceHelper.replaceCheckBoxPreferencesBySwitchPreferences(
+                getPreferenceScreen());
+    }
+
+    @Override
+    public void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mSharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
+            @Override
+            public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
+                final SubScreenFragment fragment = SubScreenFragment.this;
+                final Context context = fragment.getActivity();
+                if (context == null || fragment.getPreferenceScreen() == null) {
+                    final String tag = fragment.getClass().getSimpleName();
+                    // 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(context).dataChanged();
+                fragment.onSharedPreferenceChanged(prefs, key);
+            }
+        };
+        getSharedPreferences().registerOnSharedPreferenceChangeListener(
+                mSharedPreferenceChangeListener);
+    }
+
+    @Override
+    public void onDestroy() {
+        getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
+                mSharedPreferenceChangeListener);
+        super.onDestroy();
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
index e300bd1d3..5d77097b2 100644
--- a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
@@ -20,6 +20,7 @@ import com.android.inputmethod.dictionarypack.DictionarySettingsFragment;
 import com.android.inputmethod.latin.about.AboutPreferences;
 import com.android.inputmethod.latin.settings.AdditionalSubtypeSettings;
 import com.android.inputmethod.latin.settings.DebugSettings;
+import com.android.inputmethod.latin.settings.InputSettingsFragment;
 import com.android.inputmethod.latin.settings.SettingsFragment;
 import com.android.inputmethod.latin.spellcheck.SpellCheckerSettingsFragment;
 import com.android.inputmethod.latin.userdictionary.UserDictionaryAddWordFragment;
@@ -34,6 +35,7 @@ public class FragmentUtils {
     static {
         sLatinImeFragments.add(DictionarySettingsFragment.class.getName());
         sLatinImeFragments.add(AboutPreferences.class.getName());
+        sLatinImeFragments.add(InputSettingsFragment.class.getName());
         sLatinImeFragments.add(AdditionalSubtypeSettings.class.getName());
         sLatinImeFragments.add(DebugSettings.class.getName());
         sLatinImeFragments.add(SettingsFragment.class.getName());