如何使用 SimpleAdapter 将下载的图像显示到 ImageView

Posted

技术标签:

【中文标题】如何使用 SimpleAdapter 将下载的图像显示到 ImageView【英文标题】:How to display downloaded image to ImageView with SimpleAdapter 【发布时间】:2017-03-06 13:00:37 【问题描述】:

我正在尝试在使用简单适配器创建的 listView 的相应 ImageView 中显示图像。到目前为止,图像可以正常下载到磁盘上的某个位置,并且文本数据在 listView 中显示正常,但我无法将下载的图像显示到 listView 项目的正确位置。到目前为止,我的代码看起来像这样......

public class MainActivity extends ListActivity 
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // More Code Here
        ...

        productList = new ArrayList<HashMap<String, Object>>();

        this.getListView().setOnScrollListener(new EndlessScrollListener() 
            @Override
            public void onLoadMore(int page, int totalItemsCount) 
                // Triggered only when new data needs to be appended to the list
                // Add whatever code is needed to append new items to your
                // AdapterView
                customLoadMoreDataFromApi(page);
                // or customLoadMoreDataFromApi(totalItemsCount);
            
        );

        addInitialLoader();
        addKeyListener();

        // Get listview
        lv = getListView();

    

    // Append more data into the adapter
    public void customLoadMoreDataFromApi(int offset) 
        // This method probably sends out a network request and appends new data items to your adapter. 
        // Use the offset value and add it as a parameter to your API request to retrieve paginated data.
        // Deserialize API response and then construct new objects to append to the adapter
        //Toast.makeText(MainActivity.this,
            //"...loading more items" + offset + "...",
            //Toast.LENGTH_LONG).show();
        final Toast tost2 = Toast.makeText(MainActivity.this,
            "...loading more items" + offset + "...",
            Toast.LENGTH_LONG);
        tost2.show();

        Handler handler2 = new Handler();
        handler2.postDelayed(new Runnable() 
            @Override
            public void run() 
               tost2.cancel(); 
            
        , 1000);
    

    public void addInitialLoader() 
        // get Internet status
        isInternetPresent = cd.isConnectingToInternet();

        // check for Internet status
        if (isInternetPresent) 
            // Internet Connection is Present
            // make HTTP requests

            new JSONParse().execute();
            return;
         else 
            // Internet connection is not present
            // Ask user to connect to Internet
            showAlertDialog(MainActivity.this,
                    "No Internet Connection",
                    "You don't have internet connection.", false);
        
    

    private class JSONParse extends AsyncTask<String, String, JSONObject> 
        private ProgressDialog pDialog;

        @Override
        protected void onPreExecute() 
            super.onPreExecute();

            // Some code Here
            ...

        

        @Override
        protected JSONObject doInBackground(String... args) 
            JSONParser jParser = new JSONParser();

            // Clear previous list items
            productList.clear();

            // Getting JSON from URL
            JSONObject json = jParser.makeHttpRequest(url,
                "GET", params);

            if (json != null) 

                try 
                    // Getting JSON Array

                    Iterator<String> keys = json.keys();
                    while (keys.hasNext()) 
                        String key = keys.next();
                        String pid = "";
                        String img = "";
                        String weight = "";
                        String name = "";
                        String desciption = "";
                        String price = "";
                        int maxLen = 15;
                        int maxLen2 = 20;

                        JSONObject c = json.getJSONObject(key);
                        String err = c.getString(TAG_ERROR) == "false" ? "" : "true";

                        if (err == "true") 
                           pid = "0";
                           img = "0";
                           weight = "0";
                           name = "None";
                           desciption = "none";
                           price = "none";

                         else 
                           pid = c.getString(TAG_PID);
                           img = c.getString(TAG_IMAG);
                           weight = c.getString(TAG_SIZE);
                           name = c.getString(TAG_NAME);
                           desciption = c.getString(TAG_DESCR);
                           price = c.getString(TAG_PRICE);

                        

                        // tmp hashmap for single contact
                        HashMap<String, Object> cartitem = new HashMap<String, Object>();

                        // adding each child node to HashMap key => value
                        cartitem.put(TAG_PID, pid);
                        cartitem.put(TAG_IMAG, R.drawable.logo);
                        cartitem.put(TAG_IMP, img);
                        cartitem.put(TAG_SIZE, "Size: " + qty);
                        cartitem.put(TAG_NAME, name);
                        cartitem.put(TAG_DESCR, desciption);
                        cartitem.put(TAG_SIZE, weight);

                        if (err == "") 
                           cartitem.put(TAG_PRICE, price);
                         else 
                            cartitem.put(TAG_PRICE,
                                    "Error: No cart to show or items are already delivered.");
                        

                        // adding product details to product list
                        productList.add(cartitem);

                    

                 catch (JSONException e) 

                    Log.e("ERROR Exception: ", e.toString());
                    e.printStackTrace();
                
             else 
                // Internet connection is not present

                Log.e("ERROR Json: ", "No Internet Available");
            
            return null;
        

        @Override
        protected void onPostExecute(JSONObject json) 
            // protected void onPostExecute(Void result) 
            super.onPostExecute(json);
            // Dismiss the progress dialog
            if (pDialog.isShowing())
                pDialog.dismiss();

                /**
                * Updating parsed JSON data into ListView
                * */

                // Keys used in Hashmap
                String[] from =  TAG_SIZE, TAG_NAME, TAG_DESCR, TAG_PRICE, TAG_PID ;

                // Ids of views in listview_layout
                int[] to =  R.id.size, R.id.name, R.id.descr, R.id.price, R.id.pid ;

                ListAdapter adapter = new SimpleAdapter(MainActivity.this,
                productList, R.layout.list_item, from, to);

                setListAdapter(adapter);

                //Log.i("Adapter Count:", ""+adapter.getCount());

                for(int i=0;i<adapter.getCount();i++)
                    HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(i);

                    String imgUrl = (String) hm.get(TAG_IMP);
                    ImageLoaderTask imageLoaderTask = new ImageLoaderTask();

                    // HashMap<String, Object> hmDownload = new HashMap<String, Object>();
                    // Only put images that are set
                    String needle = "img/nophoto.png";
                    if(!needle.equals(imgUrl)) 
                        hm.put("img_path", imgUrl);
                        hm.put("position", i);
                        Log.i("HM:", hm.toString());

                        imageLoaderTask.execute(hm);
                     

                    // Starting ImageLoaderTask to download and populate image in the listview

                

            
        
    

    /** AsyncTask to download and load an image in ListView */
    private class ImageLoaderTask extends AsyncTask<HashMap<String, Object>, Void, HashMap<String, Object>>

        @Override
        protected HashMap<String, Object> doInBackground(HashMap<String, Object>... hm) 

            InputStream iStream=null;
            String imgUrl = (String) hm[0].get("img_path");
            //imgUrl = imgUrl.replace("\\/", "");
            imgUrl = imgrl + imgUrl;
            int position = (Integer) hm[0].get("position");

            Log.i("IMGURL:", imgUrl);

            URL url;
            try 
                url = new URL(imgUrl);

                // Creating an http connection to communicate with url
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

                // Connecting to url
                urlConnection.connect();

                // Reading data from url
                iStream = urlConnection.getInputStream();

                // Getting Caching directory
                File cacheDirectory = Environment.getExternalStorageDirectory(); //getBaseContext().getCacheDir();

                if (cacheDirectory.canWrite())
                    File dir = new File (cacheDirectory.getAbsolutePath() + "/IMGDir");
                    dir.mkdirs();
                    // Temporary file to store the downloaded image
                    File tmpFile = new File(dir,  "/myimg_"+position+".png");
                    Log.i("Temp:", cacheDirectory.getAbsolutePath());
                    // The FileOutputStream to the temporary file
                    FileOutputStream fOutStream = new FileOutputStream(tmpFile);

                    // Creating a bitmap from the downloaded inputstream
                    Bitmap b = BitmapFactory.decodeStream(iStream);

                    // Writing the bitmap to the temporary file as png file
                    b.compress(Bitmap.CompressFormat.PNG,100, fOutStream);

                    // Flush the FileOutputStream
                    fOutStream.flush();

                    //Close the FileOutputStream
                    fOutStream.close();

                    // Create a hashmap object to store image path and its position in the listview
                    HashMap<String, Object> hmBitmap = new HashMap<String, Object>();

                    // Storing the path to the temporary image file
                    hmBitmap.put("img",tmpFile.getPath());

                    // Storing the position of the image in the listview
                    hmBitmap.put("position",position);

                    Log.i("HMB:", hmBitmap.toString());
                    // Returning the HashMap object containing the image path and position
                    return hmBitmap;
                

            catch (Exception e) 
                e.printStackTrace();
            
            return null;
        

        @Override
        protected void onPostExecute(HashMap<String, Object> result) 
            if(result != null) 
                // Getting the path to the downloaded image
                String path = (String) result.get("img");

                // Getting the position of the downloaded image
                int position = (Integer) result.get("position");

                // Get listview
                //lv = getListView();

                // Getting adapter of the listview
                SimpleAdapter adapter = (SimpleAdapter) lv.getAdapter();

                // Getting the hashmap object at the specified position of the listview
                HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(position);
                Log.i("POS:", adapter.getItem(position).toString());
                // Overwriting the existing path in the adapter
                hm.put("image",path);

                Log.i("POS 2:", adapter.getItem(position).toString());
                // Noticing listview about the dataset changes
                //setListAdapter(adapter);
                adapter.notifyDataSetChanged();

             
        
    

感谢您在寻找连接方面的任何帮助

提前谢谢你

【问题讨论】:

您的方法似乎有点不合常规...您可以发布您的适配器代码吗?同时,看看这个,看看这里有没有什么对你有帮助:android-developers.blogspot.com/2010/07/…可能是你的ImageView需要知道哪个任务针对它,这样当它被回收时,你就没有竞争了任务。 感谢您的评论...在这种情况下没有适配器代码,因为我已经在扩展 ListActivity... 我也不想偏离这个思路。使用这种特殊方法解决的挑战激励着我 :) 在适配器的从/到映射中,我没有看到对图像/ImageView 的任何引用,所以现在我真的很困惑,我看不到适配器如何绑定图像到 ImageView 我的方法是基于这个 tut wptrafficanalyzer.in/blog/…,虽然他获取 json 数组数据,但我使用的是 json 对象,但本质上适配器更改了新的图像 url 和位置。 tut 也没有显示对 ImageView 的引用,但可以工作。我想知道我哪里出错了。如果我无法做到这一点,那么我将不得不遵循更传统的自定义适配器方法......但我只需要尝试:) 【参考方案1】:

SimpleAdapter 不具备您尝试执行的“滚动查看更多”动态更新的功能。来自文档:

将静态数据映射到 XML 文件中定义的视图的简单适配器。

一旦您传入数据的地图列表,SimpleAdapter 就无法注意到您已更新该列表。

1234563将图像添加到您的数据中。

要实现您的目标,您需要创建BaseAdapter 的子类,以便您可以动态添加数据并将图像正确绑定到ImageView

【讨论】:

以上是关于如何使用 SimpleAdapter 将下载的图像显示到 ImageView的主要内容,如果未能解决你的问题,请参考以下文章

通过 SimpleAdapter 在 imageview 中显示图像

Android:通过 SimpleAdapter 在 imageview 中显示图像

如何在 simpleAdapter 表单 URL(XML 提要)中显示图像?

ImageView 无法使用 SimpleAdapter 显示图像

如何从 SimpleAdapter 中清除元素?

如何使用 SimpleAdapter 在微调器中设置选择?