Le sous-écran de préférence ne s'ouvre pas lors de l'utilisation de support.v7.preference

J'essaie d'implémenter des préférences avec des sous-écrans utilisant AppCompatActivity et support.v7.preference

Selon les docs, chaque PreferenceScreen dans un autre PreferenceScreen fonctionne comme un sous-écran, et le cadre traitera l'affichage en cliquant dessus. Http://developer.android.com/guide/topics/ui/settings.html#Subscreens

  • Android Studio 2.2. Aperçu 1 erreur: "Utilisez JDK 8 ou plus récent"
  • Accéder à la base de données sqlite sur le périphérique Android
  • Android Fatal Signal Error 11 SIGSEGV sur différentes versions de JellyBean
  • Comment renvoyer int array de Java vers JNI
  • Meilleures pratiques lors du regroupement d'une grande quantité de marqueurs dans Google Maps Android V2
  • Forcer le son de sortie au haut-parleur interne pendant que le casque est branché
  • <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <!-- opens a subscreen of settings --> <PreferenceScreen android:key="button_voicemail_category_key" android:title="@string/voicemail" android:persistent="false"> <ListPreference android:key="button_voicemail_provider_key" android:title="@string/voicemail_provider" ... /> <!-- opens another nested subscreen --> <PreferenceScreen android:key="button_voicemail_setting_key" android:title="@string/voicemail_settings" android:persistent="false"> ... </PreferenceScreen> <RingtonePreference android:key="button_voicemail_ringtone_key" android:title="@string/voicemail_ringtone_title" android:ringtoneType="notification" ... /> ... </PreferenceScreen> ... </PreferenceScreen> 

    Cela fonctionne bien en utilisant Activity Activity, PreferenceFragment … mais en utilisant AppCompatActivity et PreferenceFragmentCompat, en cliquant sur l'élément de préférence, il suffit de le mettre en surbrillance, mais n'ouvre pas le sous-écran.

    Je n'ai rien trouvé sur cette lecture des docs et du code … Dois-je implémenter des rappels supplémentaires?


    EDIT: juste pour l'exhaustivité …

    Cela fonctionne et ouvre le sous-écran:

     public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { getFragmentManager().beginTransaction() .replace(android.R.id.content, new DemoPreferenceFragment()) .commit(); } } static public class DemoPreferenceFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } } } 

    Cela ne fonctionne pas / n'ouvre pas le sous-écran:

     public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .replace(android.R.id.content, new DemoPreferenceFragment()) .commit(); } } static public class DemoPreferenceFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle bundle, String s) { addPreferencesFromResource(R.xml.preferences); } } } 

    Modifier: 25/01/2016

    Après avoir joué avec support.v7.preference pendant quelques jours, j'ai résumé mes conclusions ici, en espérant qu'il pourrait aider les autres: comment utiliser support.v7.preference avec AppCompat et les inconvénients potentiels

  • Android Studio et Gradle build error
  • Le studio Android ouvre automatiquement la vue de documentation
  • Des solutions de rechange à CachingHttpClient pour Android?
  • Widget non teinté sur Lollipop
  • Comment afficher un seul dialogue à la fois?
  • Comment puis-je découvrir l'utilisation de la mémoire de mon application dans Android?
  • 4 Solutions collect form web for “Le sous-écran de préférence ne s'ouvre pas lors de l'utilisation de support.v7.preference”

    Il ressemble à un bug dans PreferenceFragmentCompat ou à l'insuffisance de docs. Il existe une méthode surNavigateToScreen qui est appelée lorsque vous cliquez sur l'élément PreferenceScreen.

    Mais la méthode getCallbackFragment () renvoie null par défaut, donc vous devez l'annuler dans votre fragment pour le renvoyer. De plus, vous devez implémenter PreferenceFragmentCompat.OnPreferenceStartScreenCallback.

     public class SettingsFragment extends PreferenceFragmentCompat implements PreferenceFragmentCompat.OnPreferenceStartScreenCallback { public static SettingsFragment newInstance() { return new SettingsFragment(); } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { addPreferencesFromResource(R.xml.news_settings); } @Override public Fragment getCallbackFragment() { return this; } @Override public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat, PreferenceScreen preferenceScreen) { preferenceFragmentCompat.setPreferenceScreen(preferenceScreen); return true; } } 

    Mais cela entraîne un autre problème lorsque vous ne pouvez pas revenir à votre PreferenceScreen initial,

    Une autre façon est de remplacer un fragment décrit ici. Comment revenir du sous-écran Préférences à l'écran principal dans PreferenceFragmentCompat?

    Ceci est un exemple de travail complet, j'espère que cela sera utile à quelqu'un. Il couvre l'ouverture de l'aperçu des préférences et le retour à l'écran Paramètres principaux.

    J'ai suivi ce problème dans Android open source issue tracker – ici

    La documentation officielle manque la documentation pour le chargement des sous-paramètres de préférence. Reportez-vous ici à la documentation officielle –

    L'écran principal des paramètres avancés en tant que 2 cases à cocher et un titre d'sous-écran désactivé (Paramètres de motif personnalisés): –

    Titre de sous-écran désactivé

    Une fois que nous vérifions la case à cocher Personnalisée, le titre de sous-écran est activé. Titre de sous-écran activé

    Sur le clic sur Paramètres de motif personnalisés, l'sous-écran s'ouvre dans un nouvel écran

    Entrez la description de l'image ici

    Voici le code d'exemple avec la documentation: –

    Dans fichier res / xml / preferences.xml: –

      <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:summary="Trying intro text"> <PreferenceCategory android:title="Settings"> <CheckBoxPreference android:defaultValue="true" android:key="defaultPress" android:title="Default settings" /> <CheckBoxPreference android:defaultValue="false" android:key="customKey" android:title="Custom" /> <PreferenceScreen android:key="customPrefKey" android:title="Custom Pattern Settings"> <PreferenceCategory android:key="customSettingsKey" android:title="Custom Settings"> <ListPreference android:defaultValue="4" android:entries="@array/initialClickArray" android:entryValues="@array/initialClickValues" android:key="initialClicks" android:summary="initialClicksSummary" android:title="No. Of Clicks" /> <ListPreference android:defaultValue="5" android:entries="@array/initialTimeArray" android:entryValues="@array/initialTimeValues" android:key="initialTimeKey" android:summary="Time to complete clicks" android:title="Time to complete" /> </PreferenceCategory> </PreferenceScreen> </PreferenceCategory> </PreferenceScreen> 

    MainActivity.java doit implémenter l'interface PreferenceFragmentCompat.OnPreferenceStartScreenCallback et ensuite remplacer la méthode – onPreferenceStartScreen

     public class MainActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartScreenCallback { private static final String TAG = MainActivity.class.getName(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager fragmentManager = getSupportFragmentManager(); Fragment fragment = null; if (savedInstanceState == null) { FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragment = new AdvancedSettingsFragment().newInstance("Advanced Setting"); fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit(); } } @Override public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat, PreferenceScreen preferenceScreen) { Log.d(TAG, "callback called to attach the preference sub screen"); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); AdvancedSettingsSubScreenFragment fragment = AdvancedSettingsSubScreenFragment.newInstance("Advanced Settings Subscreen"); Bundle args = new Bundle(); //Defining the sub screen as new root for the subscreen args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.getKey()); fragment.setArguments(args); ft.replace(R.id.fragment_container, fragment, preferenceScreen.getKey()); ft.addToBackStack(null); ft.commit(); return true; } 

    Pour l'écran Paramètres principaux (fragment): –

     public class AdvancedSettingsFragment extends PreferenceFragmentCompat { private static final String TAG = AdvancedSettingsFragment.class.getName(); public static final String PAGE_ID = "page_id"; public static AdvancedSettingsFragment newInstance(String pageId) { AdvancedSettingsFragment f = new AdvancedSettingsFragment(); Bundle args = new Bundle(); args.putString(PAGE_ID, pageId); f.setArguments(args); return (f); } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); final CheckBoxPreference customPreference = (CheckBoxPreference) findPreference("customKey"); final Preference customSettings = (Preference) findPreference("customPrefKey"); // First time loading the preference screen, we check the saved settings and enable/disable the custom settings, based on the custom check box //get the customSettings value from shared preferences if (getCustomSettings(getActivity())) { customPreference.setChecked(true); customSettings.setEnabled(true); } else { customPreference.setChecked(false); customSettings.setEnabled(false); } customPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object selectedValue) { Log.d(TAG, "Inside on preference change of custom checkbox selection " + selectedValue.getClass()); if ((Boolean) selectedValue) { customSettings.setEnabled(true); }else{ customSettings.setEnabled(false); } return true; } }); } private boolean getCustomSettings(Context context) { return PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean("customKey", false); } } 

    Et enfin pour le chargement du sous-écran:

     public class AdvancedSettingsSubScreenFragment extends PreferenceFragmentCompat { private static final String TAG = AdvancedSettingsSubScreenFragment.class.getName(); public static final String PAGE_ID = "page_id"; public static AdvancedSettingsSubScreenFragment newInstance(String pageId) { AdvancedSettingsSubScreenFragment f = new AdvancedSettingsSubScreenFragment(); Bundle args = new Bundle(); args.putString(PAGE_ID, pageId); f.setArguments(args); return (f); } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { // rootKey is the name of preference sub screen key name , here--customPrefKey setPreferencesFromResource(R.xml.preferences, rootKey); Log.d(TAG, "onCreatePreferences of the sub screen " + rootKey); } } 

    Une chose extrêmement importante dont vous avez besoin, vous vous souvenez:

    Votre PreferenceScreen doit contenir:

     android:key="name_a_unique_key" 

    Sinon, cela ne fonctionnera pas. J'ai passé des heures avec

    Remplacer PreferenceFragmentCompat.OnPreferenceStartScreenCallback

    Et ajouter ce qui suit à mon fragment de préférences a sauvé ma journée

     @Override public Fragment getCallbackFragment() { return this; } @Override public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen pref) { caller.setPreferenceScreen(pref); return true; } 

    Ma version de préférence est

     compile 'com.android.support:preference-v7:25.0.0' 
    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.