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

8 Comments

 Add your comment
  1. 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

  2. […] creating a custom ListPreference on the back of this […]

  3. Why can I only use up to 5 elements in the iconPicker?????

  4. Nice…Works perfect đŸ™‚

  5. 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)

  6. 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 Comment

Your email address will not be published.