6

我正在获取 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);
            }
        });

    }

这是我的布局

<?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>
4

3 回答 3

5

因此,您需要创建另一个 AsyncTask 给定一个 URL 来加载图像,并填充一些控件。我通常会做这样的事情:

ImageView imageView = (ImageView)findById(R.id.blah);
new ImageLoader( person.getImageUri(), imageView, 128, 128 ).execute();

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

然后,您可以通过创建自己的子类 ListAdapter 在将图像绑定到 ListView 时启动此 AsyncTask。因此,您将不得不放弃使用 SimpleAdapter,因为事情不再简单了。这有很多优点,因此您只需加载正在显示的图像。这意味着从总数中加载了一个非常小的数字。您的用户还可以在图像加载之前看到数据,从而更快地访问数据。如果您在现有的 AsyncTask 中执行此操作,您将加载每个图像,并且用户必须等待每个图像完成,然后才能向用户显示数据。有一些东西可以通过这个来改进。一个 AsyncTask 使用它自己的线程,因此您可能会同时运行很多线程(10 个或更多)。这可能会杀死您的服务器与大量客户端。您可以使用 ExecutorService(即线程池)将这些集中起来,但您必须放弃使用 AsyncTask 并实现自己的工具来从 UI 线程运行作业并将结果发布回 UI 线程。其次,您的图像将在用户每次滚动时加载。为此,我根据图像的 URI 实现了自己的缓存方案,因此我只加载图像一次并从缓存中返回它。在这里发布的代码有点多,但这些是给读者的练习。为此,我根据图像的 URI 实现了自己的缓存方案,因此我只加载图像一次并从缓存中返回它。在这里发布的代码有点多,但这些是给读者的练习。为此,我根据图像的 URI 实现了自己的缓存方案,因此我只加载图像一次并从缓存中返回它。在这里发布的代码有点多,但这些是给读者的练习。

另请注意,我没有在 onPostExecute() 中发回 UI 线程。那是因为 AsyncTask 为我做了这件事,我不必再做一次,正如您上面的代码所示。您应该只删除额外的可运行文件并将代码内联在 onPostExecute() 中。

于 2012-06-04T17:14:00.147 回答
1

你可以试试picasso真的很容易使用而且效果很好。

Picasso.with(this.getActivity()).load(person.getImageUri()).into(imageView); // if person.getImageUri() has the url image loaded from json

就是这样。

于 2014-09-06T07:28:16.823 回答
0

看起来你得到了多个 url(如数组)

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. 

例如懒惰的图像加载器......

http://iamvijayakumar.blogspot.in/2011/06/android-lazy-image-loader-example.html

http://codehenge.net/blog/2011/06/android-development-tutorial-asynchronous-lazy-loading-and-caching-of-listview-images/

延迟加载图像的 Android 内存不足错误

Android延迟加载图像类占用了我所有的内存

在 Android 中的 Listview 上延迟加载图像(初级)?

ListView 中图像的延迟加载

于 2012-06-04T17:05:51.680 回答