Come aprire o simulare un clic su un Android Preferenza, creato con XML, a livello di programmazione?



Answers

Vedi la nuova risposta accettata per un approccio molto più pulito! Funzionava, ma non era il modo pulito di farlo.

Dannazione, mi ci sono volute diverse ore, ma alla fine funziona.

La soluzione è la chiamata non documentata public void onItemClick (...) . Richiede diversi argomenti e, come indicato da questa domanda , può essere utilizzato per simulare un clic in base all'indice dell'elemento che si desidera chiamare.

Il mio problema era che l'oggetto che voglio chiamare è profondamente annidato in una struttura XML. Ma la soluzione è molto semplice: aggiungi una key al PreferenceScreen l'elemento che vuoi aprire è in:

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

</PreferenceScreen>

E tu puoi solo al seguente:

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

E la finestra di dialogo si apre!

Sarebbe bello avere il PreferenceScreen una Preference (quindi non dovresti sapere dove si trova la tua Preference ), perché spostando la preferenza / cambiando l'XML si potrebbe interrompere silenziosamente il dialogo automatico e non essere notato (se non testato ).

Per questo ho scritto una funzione che cercherà attraverso tutte le preferenze e restituirà la PreferenceScreen Preference su cui è attiva la tua preferenza, quindi non hai bisogno di avere la tua PreferenceScreen una chiave!

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

Ho un'applicazione Android con le preferenze dichiarate in XML, caricate con addPreferencesFromResource . L'utente può aprire le preferenze, fare clic su ciascun elemento e modificarle, tutto funziona.

Una delle preferenze che ho è:

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

Come posso mostrare automaticamente la finestra di dialogo delle preferenze a un utente (senza che l'utente debba andare alla schermata delle preferenze e fare clic su di esso?).

Ho provato ( (android.preference.DialogPreference) prefMgr.findPreference( "abc" )).showDialog(null) , ma si dice che è un metodo protetto ...? Chiamato dalla mia attività principale (che è una PreferenceActivity ), è per questo che ovviamente non può funzionare. Ma come altro?

MODIFICARE

Ho appena trovato due thread ( 1 e 2 ) con l'idea di usare findViewById per accedere alle preferenze, ma senza successo. Restituisce sempre null (fa anche per me).

Sembra che non ci sia davvero alcuna possibilità di farlo dal codice.




Migliorare la risposta di 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;
        }
    }
}



aspetta, puoi fare qualcosa di simile

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





Related