studio getpreferences getboolean android xml

android - getpreferences - ¿Qué usar en lugar de "addPreferencesFromResource" en una PreferenceActivity?



sharedpreferences en android studio (6)

@Garret Wilson ¡Muchas gracias! Como noob para la codificación de Android, me he quedado estancado con el problema de incompatibilidad de preferencias durante tantas horas, y me resulta tan decepcionante que desaprobó el uso de algunos métodos / enfoques para los nuevos que no son compatibles con las API más antiguas. tener que recurrir a todo tipo de soluciones para que su aplicación funcione en una amplia gama de dispositivos. ¡Es realmente frustrante!

Su clase es excelente, ya que le permite seguir trabajando en las nuevas API con las preferencias como solía ser, pero no es compatible con versiones anteriores. Dado que estoy tratando de llegar a una amplia gama de dispositivos, jugué un poco con él para que funcionara en los dispositivos anteriores a la API 11, así como en las nuevas API:

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

Soy un noob a la codificación de Android, y no soy el mejor fanático de Java.

Para evitar la advertencia obsoleta y forzar a Eclipse a que me permita compilar, tuve que recurrir a las anotaciones, pero estas parecen afectar solo a las clases o los 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 identificador de recursos xml dos veces cada vez que copio y pego la clase para una nueva Actividad de Preferencia, así que creé una nueva variable para almacenar este valor.

Espero que esto sea de utilidad para otra persona.

PD: Perdón por mis opiniones opinadas, pero cuando llegas nuevo y encuentras esas desventajas, ¡no puedes evitarlo sino frustrarte!

Acabo de notar el hecho de que el método addPreferencesFromResource(int preferencesResId) está marcado en desuso en la documentación de Android ( entrada de referencia ).

Desafortunadamente, 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 preferencesScreen.xml a la PreferenceActivity correspondiente?


En lugar de excepciones, simplemente use:

if (Build.VERSION.SDK_INT >= 11)

y use

@SuppressLint("NewApi")

Para suprimir las advertencias.


En lugar de usar un PreferenceActivity para cargar directamente las preferencias, use un 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 tienes tus preferencias XML ya creadas.

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 carga 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 la docs desarrolladores de Android para PreferenceFragmentCompat .


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

Además, proporciona compatibilidad descendente con Android <3.

Acabo de reconocer que mi solución está aún más cerca de la de Kevin Remo . Es solo un poquito más limpio (ya que no se basa en el antipattern de "explicación" ).

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 (i.e. API lvl * < 11). */ @SuppressWarnings("deprecation") private void onCreatePreferenceActivity() { addPreferencesFromResource(R.xml.preferences); } /** * Wraps {@link #onCreate(Bundle)} code for Android >= 3 (i.e. 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 .


No se proporciona ningún método alternativo en la descripción del método porque el enfoque preferido (a partir del nivel 11 de la API) es instanciar 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 , descubrí 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 debe hacer es crear una clase de fragmento interno, mover addPreferencesFromResources() al fragmento e invocar el fragmento desde la actividad, como esto:

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 anote aquí.