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();
}
}
}
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);
}
}