45 votes

Comment ouvrir ou de simuler un clic sur un android Préférence, créé avec XML, par programmation?

J'ai une application android avec des préférences déclarées en XML, chargé d' addPreferencesFromResource. L'utilisateur peut ouvrir les préférences, cliquez sur chaque élément et de les éditer, de toutes les œuvres.

Une préférence que j'ai est:

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

Comment puis-je afficher la boîte de dialogue préférences d'un utilisateur de manière automatique (sans le besoin de l'utilisateur pour accéder à l'écran de préférences et cliquez sur elle?).

J'ai essayé d' ( (android.preference.DialogPreference) prefMgr.findPreference( "abc" )).showDialog(null), mais il est dit que c'est une méthode protégée...? Il l'a appelé de mon activité principale (qui est un PreferenceActivity), c'est pourquoi il ne peut évidemment pas de travail. Mais comment faire autrement?

MODIFIER

Je viens de trouver deux threads (1et 2) avec l'idée d'utiliser findViewById pour accéder à la préférence, mais sans succès. Elle renvoie toujours null (pour moi aussi).

Il semble comme il n'y a vraiment aucune possibilité de le faire à partir du code.

37voto

markus Points 1327

Voir le nouveau accepté de réponse beaucoup plus propre approche! C'était du travail, mais pas vraiment le propre façon de faire.


Putain, il m'a eu plusieurs heures, mais il fonctionne enfin.

La solution est le sans-papiers, appel public void onItemClick (...). Il prend plusieurs arguments, et comme l'a souligné à cette question, il peut être utilisé pour simuler un clic selon l'indice de l'élément que vous souhaitez appeler.

Mon problème était le point je tiens à appeler est profondément imbriquée dans un XML de la structure. Mais la solution est très simple: ajouter un key de la PreferenceScreen l'élément que vous souhaitez ouvrir est dans:

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

</PreferenceScreen>

Et la vous pouvez simplement à la suivante:

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

Et la boîte de Dialogue pop-up!

Il serait agréable de se PreferenceScreen un Preference est (de sorte que vous n'aurait pas à savoir où votre Preference est), parce que le déplacement de la préférence/modifier le XML pourrait briser le automatique de la boîte de dialogue en silence et de ne pas se faire remarquer (si pas testé).

Pour cela, j'ai écrit une fonction qui permet de rechercher à travers toutes les préférences et le retour de la PreferenceScreen votre préférence, de sorte que vous n'avez pas besoin d'avoir votre PreferenceScreen une clé!

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

23voto

Jabari Points 902

Vous pourriez avoir étendu ListPreference pour créer votre boîte de dialogue, puis inclus votre propre méthode publique qui appelle le protégé méthode showDialog de ListPreference. Quelque chose comme:

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

De cette façon, vous ne rencontrerez pas de la question de la getOrder() ne fonctionne pas quand il y a des PreferenceGroups comme plusieurs personnes l'ont souligné dans les commentaires de votre réponse.

Cela peut être fait avec tout les types de préférences qui a protégé méthode showDialog.

8voto

deepak goel Points 1376
 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;
        }
    }
     }
 }  

0voto

CheckBoxPreference preference = (CheckBoxPreference) findPreference("PREF_KEY");
preference.setChecked(true);

-1voto

neelabh Points 145

attendez, u peut faire quelque chose comme ceci aussi bien

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X