¿Qué usar en lugar de “addPreferencesFromResource” en una actividad de preferencia?

Me acabo de dar cuenta del hecho de que el método addPreferencesFromResource(int preferencesResId) está marcado como obsoleto en la documentación de Android ( Entrada de referencia ).

Lamentablemente, no se proporciona ningún método alternativo en la descripción del método.

¿Qué método debería usarse en su lugar para conectar un preferenceScreen.xml a la actividad de preferencia correspondiente?

No se proporciona ningún método alternativo en la descripción del método porque el enfoque preferido (a partir del nivel API 11) es crear instancias de objetos PreferenceFragment para cargar sus preferencias desde un archivo de recursos. Vea el código de ejemplo aquí: PreferenceActivity

Para agregar más información a la respuesta correcta anterior, después de leer un ejemplo de Android-er encontré que puede convertir fácilmente su actividad de preferencia en un fragmento de preferencia. Si tienes la siguiente actividad:

 public class MyPreferenceActivity extends PreferenceActivity { @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.my_preference_screen); } } 

Los únicos cambios que tiene que hacer es crear una clase de fragmento interna, mover addPreferencesFromResources() en el fragmento e invocar el fragmento de la actividad, como este:

 public class MyPreferenceActivity extends PreferenceActivity { @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit(); } public static class MyPreferenceFragment extends PreferenceFragment { @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.my_preference_screen); } } } 

Puede haber otras sutilezas para hacer preferencias más complejas a partir de fragmentos; si es así, espero que alguien los observe aquí.

@Garret Wilson ¡Muchas gracias! Como novato de la encoding de Android, he estado atrapado con el problema de incompatibilidad de preferencias durante tantas horas, y me parece tan decepcionante que desaprobaron el uso de algunos métodos / enfoques para los nuevos que no son compatibles con las API anteriores por lo tanto tener que recurrir a todo tipo de soluciones para que su aplicación funcione en una amplia gama de dispositivos. ¡Es realmente frustrante!

Tu clase es excelente, ya que te permite seguir trabajando en nuevas API con preferencias de la forma en que solía ser, pero no es compatible con versiones anteriores. Como bash llegar a una amplia gama de dispositivos, hice algunos ajustes para que funcionen en dispositivos pre API 11 y en API más nuevas:

 import android.annotation.TargetApi; import android.os.Bundle; import android.preference.PreferenceActivity; import android.preference.PreferenceFragment; public class MyPrefsActivity extends PreferenceActivity { private static int prefs=R.xml.myprefs; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { getClass().getMethod("getFragmentManager"); AddResourceApi11AndGreater(); } catch (NoSuchMethodException e) { //Api < 11 AddResourceApiLessThan11(); } } @SuppressWarnings("deprecation") protected void AddResourceApiLessThan11() { addPreferencesFromResource(prefs); } @TargetApi(11) protected void AddResourceApi11AndGreater() { getFragmentManager().beginTransaction().replace(android.R.id.content, new PF()).commit(); } @TargetApi(11) public static class PF extends PreferenceFragment { @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(MyPrefsActivity.prefs); //outer class // private members seem to be visible for inner class, and // making it static made things so much easier } } } 

Probado en dos emuladores (2.2 y 4.2) con éxito.

Por qué mi código se ve tan malo:

Soy un novato en la encoding de Android, y no soy el mejor fanático de Java.

Para evitar la advertencia obsoleta y obligar a Eclipse a que me permitiera comstackr, tuve que recurrir a anotaciones, pero estas parecen afectar solo a las clases o métodos, así que tuve que mover el código a dos nuevos métodos para aprovechar esto.

No me gustaría tener que escribir mi id. De recurso xml dos veces cada vez que copie y pegue la clase para una nueva actividad de preferencia, así que creé una nueva variable para almacenar este valor.

Espero que esto sea útil para otra persona.

PD: Lo siento por mis puntos de vista obstinados, pero cuando eres nuevo y encuentras tales desventajas, no puedes evitarlo, ¡pero frustrarte!

Mi enfoque es muy similar al de Garret Wilson (gracias, te voté;)

Además, proporciona compatibilidad con Android <3.

Acabo de reconocer que mi solución es aún más cercana a la de Kevin Remo . Es un poco más limpio (ya que no depende del antipatrón “expection” ).

 public class MyPreferenceActivity extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { onCreatePreferenceActivity(); } else { onCreatePreferenceFragment(); } } /** * Wraps legacy {@link #onCreate(Bundle)} code for Android < 3 (ie API lvl * < 11). */ @SuppressWarnings("deprecation") private void onCreatePreferenceActivity() { addPreferencesFromResource(R.xml.preferences); } /** * Wraps {@link #onCreate(Bundle)} code for Android >= 3 (ie API lvl >= * 11). */ @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void onCreatePreferenceFragment() { getFragmentManager().beginTransaction() .replace(android.R.id.content, new MyPreferenceFragment ()) .commit(); } } 

Para un ejemplo “real” (pero más complejo) vea NusicPreferencesActivity y NusicPreferencesFragment .

En lugar de excepciones, solo use:

 if (Build.VERSION.SDK_INT >= 11) 

y use

 @SuppressLint("NewApi") 

para suprimir las advertencias

En lugar de utilizar PreferenceActivity para cargar preferencias directamente, use una AppCompatActivity o equivalente que cargue un PreferenceFragmentCompat que cargue sus preferencias. Es parte de la biblioteca de soporte (ahora Android Jetpack) y proporciona compatibilidad con API 14.

En su build.gradle , agregue una dependencia para la biblioteca de soporte de preferencias:

 dependencies { // ... implementation "androidx.preference:preference:1.0.0-alpha1" } 

Nota: Vamos a suponer que tiene sus preferencias XML ya creado.

Para su actividad, cree una nueva clase de actividad. Si está utilizando temas materiales, debe extender una AppCompatActivity , pero puede ser flexible con esto:

 public class MyPreferencesActivity extends AppCompatActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_preferences_activity) if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, MyPreferencesFragment()) .commitNow() } } } 

Ahora, para la parte importante: crea un fragmento que cargue tus preferencias desde XML:

 public class MyPreferencesFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.my_preferences_fragment); // Your preferences fragment } } 

Para obtener más información, lea los documentos de Desarrolladores de Android para PreferenceFragmentCompat .