Android: Display image in imageview by SimpleAdapter

20,841

Solution 1

Okay. So I assume here that you insist on using SimpleAdapter. No probem, problem solved, just follow the steps:

First lets create our custom row.xml for our ListView which will consist of only one ImageView.(You can add whatever you like to it later on but now i'll assume that you only wanna load the ImageView)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="5dp"
        android:src="@drawable/ic_launcher" />


</RelativeLayout>

Second lets create our custom SimpleAdapter

package com.example.helpstack;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SimpleAdapter;

public class MySimpleAdapter extends SimpleAdapter {
    private Context mContext;
    public LayoutInflater inflater = null;

    public MySimpleAdapter(Context context,
            List<? extends Map<String, ?>> data, int resource, String[] from,
            int[] to) {
        super(context, data, resource, from, to);
        mContext = context;
        inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View vi = convertView;
        if (convertView == null)
            vi = inflater.inflate(R.layout.row, null);

        HashMap<String, Object> data = (HashMap<String, Object>) getItem(position);

        new DownloadTask((ImageView) vi.findViewById(R.id.imageView1))
                .execute((String) data.get("uri"));

        return vi;
    }

}

Third lets create our DownloadTask, this class will download the image:

package com.example.helpstack;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

public class DownloadTask extends AsyncTask<String, Void, Boolean> {
    ImageView v;
    String url;
    Bitmap bm;

    public DownloadTask(ImageView v) {
        this.v = v;
    }

    @Override
    protected Boolean doInBackground(String... params) {
        url = params[0];
        bm = loadBitmap(url);
        return true;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        v.setImageBitmap(bm);
    }

    public static Bitmap loadBitmap(String url) {
        try {
            URL newurl = new URL(url);
            Bitmap b = BitmapFactory.decodeStream(newurl.openConnection()
                    .getInputStream());
            return b;
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

Now the DownloadTask is being used from inside the getView() in SimpleAdapter

Fourth lets run our amazing small project from our MainActivity.java

package com.example.helpstack;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends Activity {
    ListView lv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv = (ListView) findViewById(R.id.listView1);
        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("uri",
                "http://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png");
        //here u can add as many uri as u want
        data.add(map);
        MySimpleAdapter adapter = new MySimpleAdapter(MainActivity.this, data,
                R.layout.row, new String[] {}, new int[] {});
        lv.setAdapter(adapter);
    }
}

Solution 2

You can use any image cache library. Example, Picasa, Universal Image Loader..

You can cache the images from the URL and then you can use the images in your app.

You can find the libraries in the following links

http://square.github.io/picasso/ and https://github.com/nostra13/Android-Universal-Image-Loader

Solution 3

1) To set the image Uri to the ImageView you can use a ViewBinder
You have to implement the abstract class and override setViewValue

2) You can use Picasso to load the images in a background thread and cache them. The setViewValue method would look like this:

boolean setViewValue (View view, Object data, String textRepresentation) {
  if(view.getId() == R.id.imageView1) {
    Picasso.with(view.getContext()).load(textRepresentation).into((ImageView) view);
    return true;
  }
  return false;
}

You return true if you want to take care of the binding. You return false for the default behavior.

3) Set your adapter to use the ViewBinder by calling adapter.setViewBinder(ViewBinder);

Solution 4

You can use multiple thread to download and decode bitmap .please follow this website and try to learn how android Developer use thread pool executer to execute different image in thread. http://developer.android.com/training/multiple-threads/create-threadpool.html

Solution 5

for now, my suggestion for you is:
1. download the image from url
2. save it as drawable in the storage
3. set this drawable to the image src of imageview
(I didn't see you do this part of job from your code...)

Share:
20,841
Vuthy Sok
Author by

Vuthy Sok

Updated on August 25, 2020

Comments

  • Vuthy Sok
    Vuthy Sok over 3 years

    I am new android now I want to display image from an url. I am using imageview in listview. I want to add the list of images into the each row of the list item. I used SimpleAdapter but the imageview shows blank.

    Here's the main activity:

    package com.example.mysqltest;
    
        import java.util.ArrayList;
        import java.util.HashMap;
        import org.json.JSONArray;
        import org.json.JSONException;
        import org.json.JSONObject;
        import android.app.ListActivity;
        import android.app.ProgressDialog;
        import android.content.Intent;
        import android.os.AsyncTask;
        import android.os.Bundle;
        import android.view.View;
        import android.widget.AdapterView;
        import android.widget.AdapterView.OnItemClickListener;
        import android.widget.ListAdapter;
        import android.widget.ListView;
        import android.widget.SimpleAdapter;
    
        public class ReadComments extends ListActivity {
    
            // Progress Dialog
            private ProgressDialog pDialog;
    
            // testing on Emulator:
            private static final String READ_COMMENTS_URL = "http://192.168.30.198/test/webservice/comments.php";
    
    
            // JSON IDS:
            private static final String TAG_SUCCESS = "success";
            private static final String TAG_TITLE = "title";
            private static final String TAG_POSTS = "posts";
            private static final String TAG_POST_ID = "post_id";
            private static final String TAG_USERNAME = "username";
            private static final String TAG_MESSAGE = "message";
            private static final String TAG_IMAGE = "image";
    
    
            // An array of all of our comments
            private JSONArray mComments = null;
            // manages all of our comments in a list.
            private ArrayList<HashMap<String, String>> mCommentList;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                // note that use read_comments.xml instead of our single_post.xml
                setContentView(R.layout.read_comments);
            }
    
            @Override
            protected void onResume() {
                // TODO Auto-generated method stub
                super.onResume();
                // loading the comments via AsyncTask
                new LoadComments().execute();
            }
    
            public void addComment(View v) {
                Intent i = new Intent(ReadComments.this, AddComment.class);
                startActivity(i);
            }
    
            /**
             * Retrieves recent post data from the server.
             */
            public void updateJSONdata() {
                mCommentList = new ArrayList<HashMap<String, String>>();
    
                JSONParser jParser = new JSONParser();      
                JSONObject json = jParser.getJSONFromUrl(READ_COMMENTS_URL);
    
                try {
                    mComments = json.getJSONArray(TAG_POSTS);
    
                    for (int i = 0; i < mComments.length(); i++) {
                        JSONObject c = mComments.getJSONObject(i);
    
                        // gets the content of each tag
                        String title = c.getString(TAG_TITLE);
                        String content = c.getString(TAG_MESSAGE);
                        String username = c.getString(TAG_USERNAME);
                        String image = c.getString(TAG_IMAGE);
    
                        // creating new HashMap
                        HashMap<String, String> map = new HashMap<String, String>();
    
                        map.put(TAG_TITLE, title);
                        map.put(TAG_MESSAGE, content);
                        map.put(TAG_USERNAME, username);
                        map.put(TAG_IMAGE, image);
    
                        // adding HashList to ArrayList
                        mCommentList.add(map);
                    }
    
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
    
            /**
             * Inserts the parsed data into the listview.
             */
            private void updateList() { 
                ListAdapter adapter = new SimpleAdapter(this, mCommentList,
                        R.layout.single_post, new String[] { TAG_TITLE, TAG_MESSAGE,
                                TAG_USERNAME,TAG_IMAGE }, new int[] { R.id.title, R.id.message,
                                R.id.username, R.id.imageView1 });
    
                // I shouldn't have to comment on this one:
                setListAdapter(adapter);    
    
                ListView lv = getListView();    
                lv.setOnItemClickListener(new OnItemClickListener() {
    
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {}
                });
            }
    
            public class LoadComments extends AsyncTask<Void, Void, Boolean> {
    
                @Override
                protected void onPreExecute() {
                    super.onPreExecute();
                    pDialog = new ProgressDialog(ReadComments.this);
                    pDialog.setMessage("Loading Comments...");
                    pDialog.setIndeterminate(false);
                    pDialog.setCancelable(true);
                    pDialog.show();
                }
    
                @Override
                protected Boolean doInBackground(Void... arg0) {
                    updateJSONdata();
                    return null;
    
                }
    
                @Override
                protected void onPostExecute(Boolean result) {
                    super.onPostExecute(result);
                    pDialog.dismiss();
                    updateList();
                }
            }
        }