java 如何从android中的json数据在ImageView上显示图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10885081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to display images on ImageView from json data in android
提问by Om3ga
I am getting json data. In that json I have a url for an image. Now I want to display that Image in ImageView. How can I do acheive this? Here is my code
我正在获取 json 数据。在那个 json 中,我有一个图像的 url。现在我想在 ImageView 中显示该图像。我怎样才能做到这一点?这是我的代码
class LoadInbox extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Home.this);
pDialog.setMessage("Loading Inbox ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting Inbox JSON
* */
protected String doInBackground(String... arg0) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
JSONObject json = userFunctions.homeData();
Log.e("Data", json.toString());
// Check your log cat for JSON reponse
Log.d("Inbox JSON: ", json.toString());
try {
data = json.getJSONArray(TAG_DATA);
Log.d("inbox array: ", data.toString());
// looping through All messages
for (int i = 0; i < data.length(); i++) {
JSONObject c = data.getJSONObject(i);
// Storing each json item in variable
String profile_img = c.getString(TAG_PROFILE_IMG);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_PROFILE_IMG, profile_img);
// adding HashList to ArrayList
inboxList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
Home.this, inboxList,
R.layout.home_list_item, new String[] { TAG_PROFILE_IMG },
new int[] { R.id.profile_img2 });
// updating listview
setListAdapter(adapter);
}
});
}
here is my layout
这是我的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="@+id/profile_img2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="8dip"
android:paddingLeft="8dip"
android:paddingBottom="4dip" />
</RelativeLayout>
采纳答案by chubbsondubs
So you'll want to create another AsyncTask that given a URL will load the image, and populate some control. I typically do something like this:
所以你需要创建另一个 AsyncTask 给定一个 URL 将加载图像,并填充一些控件。我通常做这样的事情:
ImageView imageView = (ImageView)findById(R.id.blah);
new ImageLoader( person.getImageUri(), imageView, 128, 128 ).execute();
The ImageLoader would be another AsyncTask like this:
ImageLoader 将是另一个像这样的 AsyncTask:
public class ImageLoader extends AsyncTask<URI,Integer,BitmapDrawable> {
private Uri imageUri;
private ImageView imageView;
private int preferredWidth = 80;
private int preferredHeight = 80;
public ImageLoader( URI uri, ImageView imageView, int scaleWidth, int scaleHeight ) {
this.imageUri = uri;
this.imageView = imageView;
this.preferredWidth = scaleWidth;
this.preferredHeight = scaleHeight;
}
public BitmapDrawable doInBackground(URI... params) {
if( imageUri == null ) return null;
String url = imageUri.toString();
if( url.length() == 0 ) return null;
HttpGet httpGet = new HttpGet(url);
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute( httpGet );
InputStream is = new BufferedInputStream( response.getEntity().getContent() );
try {
Bitmap bitmap = BitmapFactory.decodeStream(is);
if( preferredWidth > 0 && preferredHeight > 0 && bitmap.getWidth() > preferredWidth && bitmap.getHeight() > preferredHeight ) {
return Bitmap.createScaledBitmap(bitmap, preferredWidth, preferredHeight, false);
} else {
return bitmap;
}
} finally {
is.close();
}
}
}
public void onPostExecute( BitmapDrawable drawable ) {
imageView.setImageBitmap( drawable );
}
}
Then you can kick this AsyncTask off when the image is being bound in your ListView by creating your own subclass ListAdapter. So you'll have to ditch using SimpleAdapter because things aren't simple anymore. This has a lot of advantages so you only load the images being displayed. That means a very small number is loaded out of the total. Also your user can see the data before the image loads so quicker access to the data. If you did this in your existing AsyncTask you'd load every image, and the user would have to wait for every single one to finish before the data is shown to the user. There are somethings that can be improved by this. One AsyncTask uses its own thread so you'll be running a lot of threads potentially (10 or more) all at once. That can kill your server with lots of clients. You can centralize these using an ExecutorService (ie thread pool) but you'll have to ditch using AsyncTask and implement your own facility to run the job off the UI thread and post the results back on the UI thread. Second, your images will load every time the user scrolls. For this I implemented my own caching scheme based on the URI of the image so I only load the image once and return it from the cache. It's a little too much code to post here, but these are exercises for the reader.
然后,您可以通过创建自己的子类 ListAdapter 在图像绑定到 ListView 时关闭此 AsyncTask。所以你必须放弃使用 SimpleAdapter 因为事情不再简单了。这有很多优点,因此您只需加载正在显示的图像。这意味着从总数中加载了非常小的数字。此外,您的用户可以在图像加载之前查看数据,从而更快地访问数据。如果您在现有的 AsyncTask 中执行此操作,您将加载每个图像,并且用户必须等待每个图像完成才能向用户显示数据。有一些事情可以通过这个改进。一个 AsyncTask 使用自己的线程,因此您可能会同时运行很多线程(10 个或更多)。这可能会杀死具有大量客户端的服务器。您可以使用 ExecutorService(即线程池)集中这些,但您必须放弃使用 AsyncTask 并实现您自己的工具以从 UI 线程运行作业并将结果发布回 UI 线程。其次,每次用户滚动时,您的图像都会加载。为此,我根据图像的 URI 实现了自己的缓存方案,因此我只加载图像一次并从缓存中返回它。在这里发布的代码有点太多,但这些是为读者提供的练习。为此,我根据图像的 URI 实现了自己的缓存方案,因此我只加载图像一次并从缓存中返回它。在这里发布的代码有点太多,但这些是为读者提供的练习。为此,我根据图像的 URI 实现了自己的缓存方案,因此我只加载图像一次并从缓存中返回它。在这里发布的代码有点太多,但这些是为读者提供的练习。
Also notice I'm not posting back to the UI thread in onPostExecute(). That's because AsyncTask does that for me I don't have to do it again as your code above shows. You should just remove that extra runnable and inline the code in onPostExecute().
还要注意我没有在 onPostExecute() 中回发到 UI 线程。那是因为 AsyncTask 为我做了这件事,我不必再像上面的代码所示那样做。您应该删除额外的 runnable 并内联 onPostExecute() 中的代码。
回答by ziniestro
回答by Dheeresh Singh
As it looks you are getting the more than one url (as in array)
看起来你得到的网址不止一个(如数组)
1- Keep all the url in an hastable with key as url and value as image View.
2- Show your UI and with loading image.
3- create the other task download image one by one and update in the image view.
as example lazy imageloader......
例如懒惰的图像加载器......
http://iamvijayakumar.blogspot.in/2011/06/android-lazy-image-loader-example.html
http://iamvijayakumar.blogspot.in/2011/06/android-lazy-image-loader-example.html
Android Out of Memory error with Lazy Load images
Android lazy loading images class eats up all my memory
Lazy Load images on Listview in android(Beginner Level)?
在android(初学者级别)的Listview上延迟加载图像?