25

I have been searching about ListDialogs . Whenever you can put the item you want with the :

builder.setItems(items, new DialogInterface.OnClickListener() 
{
   public void onClick(DialogInterface dialog, int item) 
   {
                        
   }
});

And thinking about the the items object, which is a CharSequence like this:

CharSequence[] items = getResources().getStringArray(R.array.share_dialog_list);

I want to know if there is a way (someone other must have made it) to make this exist, but using a custom view with icons to the left, like this:

enter image description here

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
A.Quiroga
  • 5,704
  • 6
  • 37
  • 58

2 Answers2

64

Here is a complete solution with an extended ArrayAdapter that allows icons.

See design notes for dialogs at http://developer.android.com/design/building-blocks/dialogs.html Iconogaphy at http://developer.android.com/design/style/iconography.html and IconPacks at http://developer.android.com/design/downloads/index.html

Note that the size for these looks pretty good at 48 x 48 dp, which isn't a bundled size, so you'll have to scale your own icon from the downloads.

USAGE:

            @Override
        public void onClick(View v) {
            final String [] items = new String[] {"From Gallery", "From Camera"};
            final Integer[] icons = new Integer[] {R.drawable.dialog_gallery_icon, R.drawable.dialog_camera_icon};
            ListAdapter adapter = new ArrayAdapterWithIcon(getActivity(), items, icons);

            new AlertDialog.Builder(getActivity()).setTitle("Select Image")
                .setAdapter(adapter, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int item ) {
                        Toast.makeText(getActivity(), "Item Selected: " + item, Toast.LENGTH_SHORT).show();
                    }
            }).show();
        }

ArrayAdapterWithIcon.java

public class ArrayAdapterWithIcon extends ArrayAdapter<String> {

private List<Integer> images;

public ArrayAdapterWithIcon(Context context, List<String> items, List<Integer> images) {
    super(context, android.R.layout.select_dialog_item, items);
    this.images = images;
}

public ArrayAdapterWithIcon(Context context, String[] items, Integer[] images) {
    super(context, android.R.layout.select_dialog_item, items);
    this.images = Arrays.asList(images);
}

public ArrayAdapterWithIcon(Context context, int items, int images) {
    super(context, android.R.layout.select_dialog_item, context.getResources().getTextArray(items));

    final TypedArray imgs = context.getResources().obtainTypedArray(images);
    this.images = new ArrayList<Integer>() {{ for (int i = 0; i < imgs.length(); i++) {add(imgs.getResourceId(i, -1));} }};

    // recycle the array
    imgs.recycle();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = super.getView(position, convertView, parent);
    TextView textView = (TextView) view.findViewById(android.R.id.text1);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        textView.setCompoundDrawablesRelativeWithIntrinsicBounds(images.get(position), 0, 0, 0);
    } else {
        textView.setCompoundDrawablesWithIntrinsicBounds(images.get(position), 0, 0, 0);
    }
    textView.setCompoundDrawablePadding(
            (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, getContext().getResources().getDisplayMetrics()));
    return view;
}

}
Gavriel
  • 18,880
  • 12
  • 68
  • 105
aaronvargas
  • 12,189
  • 3
  • 52
  • 52
  • The Icon doesn't change size based on screen size... does it? – Si8 Sep 06 '13 at 20:23
  • 1
    @SiKni8, you'd have to provide different resource drawables if you wanted them at different sizes for other screen sizes. – aaronvargas Sep 07 '13 at 15:32
  • @SiKni8 : since you're referencing resource drawables, the right one is taken depending on the screen size, if you put it in the right directory (res/drawable-?dpi/) – Quentin S. Feb 09 '14 at 18:03
  • @aaronvargas ... I have used your snippet for alertDialog but getActivity() its not recognizing... when i am putting the code in MainActivity.class – anand Sep 25 '14 at 13:18
  • getActivity() is used for getting the Context. If you're using it IN an Activity use 'this' instead since Activity is a Context. – aaronvargas Sep 25 '14 at 23:07
  • I've used this and it works great. However, when setting the language to a RTL language like Hebrew or Arabic, the icons still appear on the left side, before the text. Is there anyway to get them to reverse and appear on the right for RTL languages? – gbotha Sep 26 '14 at 02:43
  • 2
    @gbotha, looks like you need to change textView.setCompoundDrawablesWithIntrinsicBounds() to textView.setCompoundDrawablesRelativeWithIntrinsicBounds() and leave the arguments the same. This was added in API 17, see this question for more help with previous API levels, http://stackoverflow.com/questions/18996183/identifyng-rtl-language-in-android – aaronvargas Sep 26 '14 at 23:38
  • @aaronvargas Thanks so much. Just tested that out and it works great!! – gbotha Sep 27 '14 at 00:17
  • @Gavriel, can you either remove the commented code or figure out 'this doesn't work for some reason'? Getting arrays from resources is not core to keeping this answer simple and concise and can be done externally. – aaronvargas Mar 15 '16 at 17:43
3

make the custom view like we create for the list view

alert_customlist.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp" android:background="#ffffffff">
    <ImageView android:layout_width="50dp" android:layout_height="50dp"
        android:textColor="#ffff0000" android:textSize="20dp" android:id="@+id/text1"/>
    <TextView android:text="text view two" android:layout_width="fill_parent" android:layout_height="wrap_content" 
        android:textColor="#ffff0000" android:textSize="20dp" android:id="@+id/text2"/>
</LinearLayout>

now add this view into the AlertDialog.

RonTLV
  • 2,376
  • 2
  • 24
  • 38
Pratik
  • 30,639
  • 18
  • 84
  • 159