support last android appcompat android-preferences

com.android.support:appcompat-v7 last version



La subpantalla de preferencias no se abre cuando se usa support.v7.preference (5)

Estoy tratando de implementar preferencias con sub-pantallas usando AppCompatActivity y support.v7.preference

De acuerdo con los documentos, cada PreferenceScreen dentro de otra PreferenceScreen funciona como una subpantalla, y el marco manejará mostrarlo cuando se haga clic. http://developer.android.com/guide/topics/ui/settings.html#Subscreens

<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>

Esto funciona bien usando la Actividad nativa, PreferenceFragment ... pero usando AppCompatActivity y PreferenceFragmentCompat, al hacer clic en el elemento de Preferencias solo se resalta, pero no se abre la subpantalla.

No pude encontrar nada al leer los documentos y el código ... ¿necesito implementar devoluciones de llamada adicionales?

EDITAR: sólo para la integridad ...

Esto funciona y abre la subpantalla:

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); } } }

Esto no funciona / abre la subpantalla:

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); } } }

Edición: 25/01/2016

Después de jugar con support.v7.preference durante unos días, he resumido mis hallazgos aquí, con la esperanza de que pueda ayudar a otros: Cómo usar support.v7.preference con AppCompat y posibles inconvenientes


Anulación de PreferenceFragmentCompat.OnPreferenceStartScreenCallback

y agregando lo siguiente a mi fragmento de preferencia guardado mi día

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

Mi versión preferida es

compile ''com.android.support:preference-v7:25.0.0''


Este es un ejemplo completo de trabajo, espero que sea útil para alguien. Cubre abrir la subpantalla de preferencias y regresar a la pantalla principal de Configuración.

Seguí este problema en el rastreador de código abierto de Android, here

A la documentación oficial le falta la documentación para cargar la subpantalla de preferencias. Consulte aquí la documentación oficial .

La pantalla principal de configuración avanzada tiene 2 casillas de verificación y un título de sub-pantalla deshabilitado (configuración de patrón personalizado): -

Una vez que marcamos la casilla de verificación Personalizar, se habilita el título de la subpantalla.

Al hacer clic en Configuración de patrón personalizado, la pantalla secundaria se abre en una nueva pantalla

Aquí está el código de ejemplo con la documentación: -

En el archivo 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 debe implementar la interfaz PreferenceFragmentCompat.OnPreferenceStartScreenCallback y luego anular el método-- 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; }

Para la pantalla principal de configuración (fragmento):

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); } }

y finalmente para la carga de subpantallas:

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); } }



Parece un error en PreferenceFragmentCompat o insuficiencia de documentos. Tiene el método onNavigateToScreen al que se llama cuando hace clic en el elemento PreferenceScreen.

Pero el método getCallbackFragment () devuelve nulo de manera predeterminada, por lo que necesita reemplazarlo en su fragmento para devolver esto. También necesita implementar 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; } }

Pero conduce a otro problema cuando no puede volver a su Pantalla de Preferencia inicial,

Otra forma es reemplazar el fragmento que se describe aquí ¿Cómo pasar de la subpantalla de Preferencias a la pantalla principal en PreferenceFragmentCompat?


Una cosa extremadamente importante que necesitas recordar:

Su PreferenceScreen debe contener:

android:key="name_a_unique_key"

De lo contrario, no funcionará. He pasado horas con ellos