Search code examples
androidlistviewandroid-listviewimageviewcustom-adapter

ListView Custom Adapter that includes Images from gallery


When creating a custom ListView adapter, usually I extend it from Array Adapter<String> but I want to make a ListView containing photos from the Gallery of the phone.

I managed to get the Bitmap from the Gallery referring to the picture the user chose and put it in a regular ImageView but, I don't really know how to do an adapter of a ListView displaying the photos the user choose. The photos are Bitmap, any help?


Solution

  • You would do this exactly as you would do with a list that contains only text.

    First you might want to create a class that represents an item in your list (maybe you want to add some more data, like an ID or a name), like:

    class ItemInMyList {
            Bitmap image;
            String title;
            Integer id;
     }
    

    Then just create a new class that extends ArrayAdapter:

    public class MyAdapter extends ArrayAdapter<ItemInMyList> {
        private final Context context;
        private final List<ItemInMyList> values;
        private int layout;
    
        public MyAdapter(Context context, List<ItemInMyList> values, int layout) {
            super(context, layout, values);
            this.context = context;
            this.values = values;
            this.layout = layout;
        }
    
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
            // When convertView is not null, we can reuse it directly, there is no need
            // to reinflate it. We only inflate a new View when the convertView supplied
            // by ListView is null.
            if (convertView == null) {
                convertView = inflater.inflate(layout, null);
                // Creates a ViewHolder and store references to the two children views
                // we want to bind data to.
                holder = new ViewHolder();
                holder.name= (TextView) convertView.findViewById(R.id.name);
                holder.image = (ImageView) convertView.findViewById(R.id.image);
                // Bind the data efficiently with the holder.
                convertView.setTag(holder);
            } else {
                // Get the ViewHolder back to get fast access to the TextView
                // and the ImageView.
                holder = (ViewHolder) convertView.getTag();
            }
            try {
                holder.text.setText(values.get(position).title);
                // Set your image to the ImageView in your list layout
                holder.image.setImageBitmap(values.get(position).image);
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
            return convertView;
        }
    
        static class ViewHolder {
            TextView name;
            ImageView image;
        }
    }
    

    Now you just need to create a layout that represents a row in your ListView. In this example you would likely add an ImageView (image) and a TextView (name) to a LinearLayout.

    Then when you instanciate the adapter, just give it the layout for the row:

    new MyAdapter(this, data, R.layout.rowlayout);
    

    That's it, basically.