Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


¿Cómo abrir o simular un clic en una preferencia de Android, creado con XML, mediante programación?

Tengo una aplicación de Android con las preferencias declaradas en XML, cargado con addPreferencesFromResource . El usuario puede abrir las preferencias, hacer clic en cada elemento y editarlos, todo funciona.

Una preferencia que tengo es:

  <ListPreference android:key="abc" android:title="@string/abc" android:summary="@string/cde" android:persistent="true"/> 

¿Cómo puedo mostrar automáticamente el diálogo de preferencias a un usuario (sin necesidad de que el usuario vaya a la pantalla de preferencias y haga clic en él?).

He intentado ( (android.preference.DialogPreference) prefMgr.findPreference( "abc" )).showDialog(null) , pero se dice que es un método protegido …? Lo llamó de mi actividad principal (que es una PreferenceActivity ), por eso es obvio que no puede funcionar. Pero, ¿qué más?

EDITAR

Acabo de encontrar dos hilos ( 1 , y 2 ) con la idea de utilizar findViewById para acceder a la preferencia, pero sin éxito. Siempre devuelve null (hace por mí, también).

Parece que realmente no hay posibilidad de hacer esto desde el código.

7 Solutions collect form web for “¿Cómo abrir o simular un clic en una preferencia de Android, creado con XML, mediante programación?”

Podría haber extendido ListPreference para crear su diálogo, luego incluyó su propio método público que llama al método showDialog protegido de ListPreference. Algo como:

 public void show() { showDialog(null); } 

De esta manera no se ejecutará en el problema de getOrder () no funciona cuando hay grupos de preferencias como varias personas han señalado en los comentarios de su respuesta.

Esto se puede hacer con cualquier tipo de preferencia que tenga un método showDialog protegido.

¡Vea la nueva respuesta aceptada para un enfoque mucho más limpio! Esto estaba funcionando, pero no realmente la manera limpia de hacerlo.


Maldita sea, me dio varias horas, pero finalmente funciona.

La solución es la llamada indocumentada public void onItemClick (...) . Se necesitan varios argumentos, y como se señala en esta pregunta puede ser utilizado para simular un clic de acuerdo con el índice del elemento que desea llamar.

Mi problema es que el elemento que quiero llamar está profundamente anidado en una estructura XML. Pero la solución es muy fácil: añada una key a la PreferenceScreen el elemento que desea abrir está en:

 <PreferenceScreen android:key="pref_key" .... /> <ListPreference android:key="abc" android:title="@string/abc" android:summary="@string/cde" android:persistent="true"/> </PreferenceScreen> 

Y lo único que puede a lo siguiente:

 // the preference screen your item is in must be known PreferenceScreen screen = (PreferenceScreen) findPreference("pref_key"); // the position of your item inside the preference screen above int pos = findPreference("abc").getOrder(); // simulate a click / call it!! screen.onItemClick( null, null, pos, 0 ); 

¡Y el diálogo aparece!

Sería bueno para obtener el PreferenceScreen una Preference está en (por lo que no tendría que saber dónde está su Preference ), porque mover la preferencia / cambiar el XML podría romper el diálogo automático en silencio y no puede notarse (si no se ha probado ).

Para esto escribí una función que buscará en todas las preferencias y devolverá la PreferenceScreen su preferencia es, por lo que no es necesario tener su PreferenceScreen una clave!

 private PreferenceScreen findPreferenceScreenForPreference( String key, PreferenceScreen screen ) { if( screen == null ) { screen = getPreferenceScreen(); } PreferenceScreen result = null; android.widget.Adapter ada = screen.getRootAdapter(); for( int i = 0; i < ada.getCount(); i++ ) { String prefKey = ((Preference)ada.getItem(i)).getKey(); if( prefKey != null && prefKey.equals( key ) ) { return screen; } if( ada.getItem(i).getClass().equals(android.preference.PreferenceScreen.class) ) { result = findPreferenceScreenForPreference( key, (PreferenceScreen) ada.getItem(i) ); if( result != null ) { return result; } } } return null; } private void openPreference( String key ) { PreferenceScreen screen = findPreferenceScreenForPreference( key, null ); if( screen != null ) { screen.onItemClick(null, null, findPreference(key).getOrder(), 0); } } // With this, you can call your `Preference` like this from code, you do // not even have to give your PreferenceScreen a key! openPreference( "abc" ); 
  PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference("pref_key"); final ListAdapter listAdapter = preferenceScreen.getRootAdapter(); EditTextPreference editPreference = (EditTextPreference) findPreference("set_password_preference"); final int itemsCount = listAdapter.getCount(); int itemNumber; for (itemNumber = 0; itemNumber < itemsCount; ++itemNumber) { if (listAdapter.getItem(itemNumber).equals(editPreference)) { preferenceScreen.onItemClick(null, null, itemNumber, 0); break; } } } } 

Mejora de la respuesta de deepak goel :

 private void openPreference(String key) { PreferenceScreen preferenceScreen = getPreferenceScreen(); final ListAdapter listAdapter = preferenceScreen.getRootAdapter(); final int itemsCount = listAdapter.getCount(); int itemNumber; for (itemNumber = 0; itemNumber < itemsCount; ++itemNumber) { if (listAdapter.getItem(itemNumber).equals(findPreference(key))) { preferenceScreen.onItemClick(null, null, itemNumber, 0); break; } } } 

Si utiliza la biblioteca de soporte, puede abrir fácilmente un cuadro de diálogo con PreferenceManager.showDialog (Preferencia) .

En su PreferenceFragmentCompat:

 getPreferenceManager().showDialog(findPreference("pref_name")); 

Tenga en cuenta que el paquete de preferencias de soporte tiene muchos problemas: estilo no material y se bloquea cuando se gira con un diálogo abierto .

Espera, u puede hacer algo como esto también

 Preference p=findPreference("settings_background_color"); p.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { int color=PreferenceManager.getDefaultSharedPreferences(ALifePatternsWallpaperSettings.this).getInt("settings_background_color", Color.BLACK); new ColorPickerDialog(ALifePatternsWallpaperSettings.this, ALifePatternsWallpaperSettings.this, "settings_background_color", color, Color.BLACK).show(); return true; } }); 

Hola amigos probar este código en funciona bien

 getPreferenceManager().findPreference("YOUR PREF_KEY").setOnPreferenceClickListener(new OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { //your code here return true; } }); 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.