Come mostrare un’icona nelle preferenze

Nelle preferenze di Android tu puoi inserire varie tipologie di controlli: check box, edit text, list,…, ma nessuna di queste prevede la visualizzazione di una icona (vedi Settings).
Normalmente una preferenza è costituita da due righe, il titolo e il sommario, e dopo aver clickato ottieni una dialog box dove poter selezionare la voce voluta, come puoi vedere nelle due figure sotto.

font_preference_arrow font_preference_dialog

Nota che nessuna icona è mostrata.

In questo articolo riporto un esempio per creare una preferenza in cui una icona è mostrata e scelta dall’utente, l’intero progetto è scaricabile da qui.

Come funziona

  1. i layout: ci sono quattro layout
    • activity_main.xml il layout per l’Activity contenente solo la TextView “Hello world!”
    • icon_item_preference.xml il layout per le preferenze, in questo esempio è costituito da un solo item contenente un titolo, un sommario e un’icona

      i valori dei padding del RelativeLayout sono quelli adatti alla versione 4.x di Android, per versioni più vecchie il paddingLeft dovrebbe essere impostato a 72dp
    • item_picker.xml il layout che gestisce la scelta dell’icona da parte dell’utente, contiene il sommario (il nome dell’icona), l’icona e un radio button
    • preferences.xml, questo layout a differenza dei precedenti non è nella directory “res/layout” ma nella directory “res/xml”, la classe IconPickerPreference fa riferimento a questo file che a sua volta ha come layout il file icon_item_preference.xml (riga 10)
  2. i file xml nella directory “values”:
    • strings.xml contiene le stringhe utilizzate nell’app e fra queste:
      • icon_default il file senza estensione dell’icona di default
      • custom_icon_key la chiave associata all’icona selezionata
      • icon_label il titolo
      • default_summary il valore iniziale del sommario
      • iconName matrice di stringhe con i nome delle icone
      • iconFile matrice di stringhe con i nomi dei file senza estensione delle icone, uno di questi è uguale a custom_icon_key

    • attrs_icon.xml definisce il custom attribute iconFile utilizzato in preferences.xml alla riga 13

  3. le classi java:
    • MainActivity.java l’activity iniziale, serve solo per lanciare le preferenze, righe 27-30

    • PreferencesActivity.java l’activity delle preferenze, contiene un’istanza di IconPickerFragment

    • IconPickerFragment.java, ha come layout il file preferences.xml

    • IconPickerPreference.java, la classe chiave dell’app, gestisce la preferenza impostata in preferences.xml e la dialog box dove l’utente sceglie l’icona
      • riga 130: il costruttore IconPickerPreference inizializza context, resources, preferences e defaultIconFile definito in preferences.xml
      • riga 155: il metodo onBindView visualizza l’icona contenuta nelle preferenze
      • riga 197: il metodo onPrepareDialogBuilder è chiamato prima dell’apertura della dialog box, definisce l’adpapter per il builder (dialog box)
      • riga 170: il metodo onDialogClosed è chiamato dopo che la dialog box è stata chiusa e salva la scelta dell’utente nelle preferenze
      • riga 27: la classe CustomListPreferenceAdapter gestisce la dialog box

Le seguenti immagini mostrano l’app:

  • MainActivity.java
    custom_preference_settings
  • PreferencesActivity.java and IconPickerFragment.java
    custom_preference_green
  • IconPickerPreference.java
    custom_preference_picker

10 risposte a “Come mostrare un’icona nelle preferenze”

  1. I tried JJ974s solution on StackOverFlow, but it does not work for several reasons:
    1) Cannot resolve symbol preference_list_icon_picker
    2) Cannot resolve methos setAdapter
    3) No imports included in sample code, which makes it difficult to know which version of Builder class is used.

    Another big problem is that Luca Zaninis original project contains lots of deprecated classes. So it is very risky to use a solution like this in production. It will probably cause lots of crashes.

    Please help me find a modern way to add icons to ListPreference! This would make apps so much more user friendly and more fun to use.

  2. Hi Luca,
    Thank you very much for your nice Listpreference with icons.
    Can I make a minor suggestion?
    I saw that the code has some depedencies beyond the listpreference (own) properties. So, re-use of the solution as-as is not easily possible. Therefore I changed the code a bit so your wonderful solution can be re-used as often as I like. Please refer to http://stackoverflow.com/a/41806449/3143823. At the forums I thanked you for the solution.
    Kind regards,
    Johan, NL

  3. Gives me this error: please help me plsss…!!!

    2918-2918/com.example.virenjaru.myapplication1 E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.virenjaru.myapplication1, PID: 2918
    java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.widget.ImageView.setImageResource(int)’ on a null object reference
    at com.example.virenjaru.myapplication1.IconPickerPreference.updateIcon(IconPickerPreference.java:234)
    at com.example.virenjaru.myapplication1.IconPickerPreference.onBindView(IconPickerPreference.java:161)
    at android.preference.Preference.getView(Preference.java:489)
    at android.preference.PreferenceGroupAdapter.getView(PreferenceGroupAdapter.java:246)
    at android.widget.AbsListView.obtainView(AbsListView.java:2344)
    at android.widget.ListView.makeAndAddView(ListView.java:1864)
    at android.widget.ListView.fillDown(ListView.java:698)
    at android.widget.ListView.fillFromTop(ListView.java:759)
    at android.widget.ListView.layoutChildren(ListView.java:1673)
    at android.widget.AbsListView.onLayout(AbsListView.java:2148)
    at android.view.View.layout(View.java:15596)
    at android.view.ViewGroup.layout(ViewGroup.java:4966)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
    at android.view.View.layout(View.java:15596)
    at android.view.ViewGroup.layout(ViewGroup.java:4966)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:508)

  4. Hi I am new to java and am following this guide. I have it working where it shows the images etc but wonder if there is a way to add a third array which contains a value to be set to the settings database? Any help on this would be appreciated.

    Thanks

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.