Android:通过 SimpleAdapter 在 imageview 中显示图像
Posted
技术标签:
【中文标题】Android:通过 SimpleAdapter 在 imageview 中显示图像【英文标题】:Android: Display image in imageview by SimpleAdapter 【发布时间】:2014-07-22 01:18:36 【问题描述】:我是新的 android 现在我想显示来自 url 的图像。我在列表视图中使用图像视图。我想将图像列表添加到列表项的每一行中。我使用了 SimpleAdapter,但 imageview 显示为空白。
这是主要活动:
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();
【问题讨论】:
SimpleAdapter.setViewImage 适用于系统资源,而不适用于网络资源。您需要下载网络图像并将位图显式设置为 ImageView。你可以试试这个answer。 感谢您的评论。你能帮我如何在我的代码中应用 setViewImage 吗? 你好@VuthySok 你在吗? 【参考方案1】:好的。所以我在这里假设你坚持使用SimpleAdapter
。没有问题,问题解决了,按照以下步骤操作:
首先让我们为我们的ListView
创建我们的自定义row.xml,它将只包含一个ImageView
。(您可以稍后添加任何您喜欢的内容,但现在我假设你只想加载ImageView
)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical" >
<ImageView
android:id="@+id/imageView1"
android:layout_
android:layout_
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:src="@drawable/ic_launcher" />
</RelativeLayout>
其次让我们创建我们的自定义 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;
第三个让我们创建我们的DownloadTask
,这个类将下载图像:
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;
现在 DownloadTask
正在 SimpleAdapter
的 getView() 内部使用
第四,让我们从 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);
【讨论】:
我确实遵循了您的代码,但运行时总是关闭应用程序 您是否在清单文件中添加了互联网权限?它不应该关闭。尝试添加权限,如果它不起作用,我会把我的样品寄给你。但我建议你告诉我们 logcat 中发生的错误是什么 是的,我确实添加了权限您可以使用任何图像缓存库。例如,Picasa、通用图像加载器..
您可以缓存来自 URL 的图片,然后您可以在您的应用中使用这些图片。
您可以在以下链接中找到这些库
http://square.github.io/picasso/ 和 https://github.com/nostra13/Android-Universal-Image-Loader
【讨论】:
【参考方案3】:您可以使用多线程下载和解码位图。请关注本网站并尝试了解android开发人员如何使用线程池执行器在线程中执行不同的图像。 http://developer.android.com/training/multiple-threads/create-threadpool.html
【讨论】:
【参考方案4】:1) 要将图像 Uri 设置为 ImageView,您可以使用 ViewBinder
你必须实现抽象类并覆盖setViewValue
2) 您可以使用Picasso 在后台线程中加载图像并缓存它们。
setViewValue
方法如下所示:
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;
如果您想处理绑定,请返回 true
。您返回 false
作为默认行为。
3) 通过调用adapter.setViewBinder(ViewBinder);
将adapter
设置为使用ViewBinder
【讨论】:
【参考方案5】:现在,我给你的建议是: 1.从url下载图片 2.将其保存为可绘制在存储中 3.将此drawable设置为imageview的图片src (我没有看到你从你的代码中完成这部分工作......)
【讨论】:
【参考方案6】:本教程是使用 json 解析来解析图像并将其显示在列表视图中的最佳示例:http://www.androidbegin.com/tutorial/android-json-parse-images-and-texts-tutorial/
其他一些:
http://imagelistviewdynamic.blogspot.in/2012/12/image-parsed-from-json-using-async-into.html
http://www.java2s.com/Open-Source/Android_Free_Code/JSON/Download_Free_code_Android_JSON_Parse_Images_and_Texts_Tutorial.htm
【讨论】:
【参考方案7】:我建议你使用Universal Image Loader,它使用异步图像下载、缓存和显示,你可以找到如何实现它的示例。完成后,您不必担心图像的数量或大小。
如果您下载该项目,您会发现这个示例可以完成您想要的所有工作:
/**
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
*/
public class ImageListActivity extends AbsListViewBaseActivity
DisplayImageOptions options;
String[] imageUrls;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.ac_image_list);
// here you get a String array with images URL
Bundle bundle = getIntent().getExtras();
imageUrls = bundle.getStringArray(Extra.IMAGES);
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory(true)
.cacheOnDisc(true)
.considerExifParams(true)
.displayer(new RoundedBitmapDisplayer(20))
.build();
listView = (ListView) findViewById(android.R.id.list);
((ListView) listView).setAdapter(new ItemAdapter());
listView.setOnItemClickListener(new OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
startImagePagerActivity(position);
);
@Override
public void onBackPressed()
AnimateFirstDisplayListener.displayedImages.clear();
super.onBackPressed();
// it gets the position of listView and opens that image in a new Activity
private void startImagePagerActivity(int position)
Intent intent = new Intent(this, ImagePagerActivity.class);
intent.putExtra(Extra.IMAGES, imageUrls);
intent.putExtra(Extra.IMAGE_POSITION, position);
startActivity(intent);
class ItemAdapter extends BaseAdapter
private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
private class ViewHolder
public TextView text;
public ImageView image;
@Override
public int getCount()
return imageUrls.length;
@Override
public Object getItem(int position)
return position;
@Override
public long getItemId(int position)
return position;
@Override
public View getView(final int position, View convertView, ViewGroup parent)
View view = convertView;
final ViewHolder holder;
if (convertView == null)
view = getLayoutInflater().inflate(R.layout.item_list_image, parent, false);
holder = new ViewHolder();
holder.text = (TextView) view.findViewById(R.id.text);
holder.image = (ImageView) view.findViewById(R.id.image);
view.setTag(holder);
else
holder = (ViewHolder) view.getTag();
holder.text.setText("Item " + (position + 1));
// here is the place where is loaded the image using Universal ImageLoader , imageUrls[position] is a list of images URL
imageLoader.displayImage(imageUrls[position], holder.image, options, animateFirstListener);
return view;
private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener
static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
if (loadedImage != null)
ImageView imageView = (ImageView) view;
boolean firstDisplay = !displayedImages.contains(imageUri);
if (firstDisplay)
FadeInBitmapDisplayer.animate(imageView, 500);
displayedImages.add(imageUri);
【讨论】:
以上是关于Android:通过 SimpleAdapter 在 imageview 中显示图像的主要内容,如果未能解决你的问题,请参考以下文章
通过 SimpleAdapter 在 imageview 中显示图像
Android--Gridview使用SimpleAdapter加载bitmap图片
Android--Gridview使用SimpleAdapter加载bitmap图片
13.Android-ListView使用BaseAdapter/ArrayAdapter/SimpleAdapter适配器使用