How to display an icon in the preferences

In the Android preferences you can put different types of controls: check box, edit box, list,…, but none of these displays an icon (see Settings).
Usually a preference consists of two lines, the title and the summary, and after you have clicked you get a dialog box where you can select the chosen item, as you can see in the two pictures below.

font_preference_arrow font_preference_dialog

Note that there are no icons.

In this post I write an example to create a preference where a icon is shown and chosen from the user, you can download the whole project here.

How it works

  1. the layouts: there are four layouts
    • activity_main.xml the layout for the Activity containing the TextView “Hello world!” only
    • icon_item_preference.xml the layout for the preferences, in this example it consists of only one item containing a title, a summary and an icon

      the padding values of the RelativeLayout are for the version 4.x of Android, for earlier versions the paddingLeft should be set to 72dp
    • item_picker.xml the layout that handles the selection of the icon from the user, it contains the summary (the name of the icon), the icon and a radio button
    • preferences.xml this layout is not in the directory “res/layout” unlike previous ones but in the directory “res/xml”, the class IconPickerPreference is bound to this file which has the file icon_item_preference.xml (line 10) as layout
  2. the files in the directory “values”:
    • strings.xml contains the strings used by the app and among these:
      • icon_default the file without extension of the default icon
      • custom_icon_key the key of the selected icon
      • icon_label the title
      • default_summary the initial value of the summary
      • iconName strings array with the names of the icons
      • iconFile strings array with the names of the files without extension of the icons, one of these is equal to custom_icon_key

    • attrs_icon.xml defines the custom attribute iconFile used in preferences.xml at the line 13

  3. the java classes:
    • MainActivity.java the starting activity, it is only to launch the preferences, lines 27-30

    • PreferencesActivity.java the activity of the preferences, it contains an instance of IconPickerFragment

    • IconPickerFragment.java, it has the file preferences.xml as layout

    • IconPickerPreference.java, the key class of the app, it handles the preference set in preferences.xml and the dialog box where the user chooses the icon
      • line 130: the constructor IconPickerPreference initializes context, resources, preferences and defaultIconFile defined in preferences.xml
      • line 155: the method onBindView displays the icon in the preferences
      • line 197: the method onPrepareDialogBuilder is called before the opening of the dialog box, it defines the adapter for the bulder (dialog box)
      • line 170: the method onDialogClosed is called after the dialog box is closed and it saves the choice of the user in the preferences
      • line 27: the class CustomListPreferenceAdapter handles the dialog box

The following pictures show the app:

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

10 Replies to “How to display an icon in the preferences”

  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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.