Android: Display image in imageview by SimpleAdapter
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...)
Vuthy Sok
Updated on August 25, 2020Comments
-
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(); } } }