在后台问题显示中下载图像

时间:2016-01-17 06:02:33

标签: android android-imageview

我目前正在做的是允许用户查找曲目,它将显示歌曲名称并显示艺术家,然后开始在后台下载图像,以便用户快速查看结果。我目前所做的是获取前10个查询并取消这些查询并下载这些图像,然后当用户点击显示更多时,它将下载10个以上等等,但是一旦完成加载后实际显示的唯一图像是第一个。其余的图像下载,但图像视图不会填充,除非我滚动它们然后回过头。我无法弄清楚原因,但这是我的代码。

自定义列表适配器的代码:

public class SearchSongAdapter extends BaseAdapter {
    ArrayList<ArrayList<String>> track_info;
    private static LayoutInflater inflater=null;
    String token;
    ArrayList<ImageView> imageViews;
    ArrayList<Bitmap> imageBitMaps;
    DownloadImageTask downloadImageTask;
    int downloadsCounter = 0;
    public SearchSongAdapter(Context context, ArrayList<ArrayList<String>> track_info, String token)
    {
        imageViews = new ArrayList<ImageView>();
        imageBitMaps = new ArrayList<Bitmap>();
        inflater = (LayoutInflater)context.
                getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.track_info = track_info;
        this.token = token;
        //start the downloads
        if(track_info.size() > 0) {
            downloadImageTask = new DownloadImageTask();
            downloadImageTask.execute("https://api.spotify.com/v1/tracks/" + track_info.get(0).get(1).replace("spotify:track:", ""), String.valueOf(downloadsCounter));
        }
    }

    @Override
    public int getCount() {
        return this.track_info.size();
    }

    @Override
    public Object getItem(int position) {
        return track_info.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public class Holder
    {
        TextView songNameTextView, artistNameTextView;
        ImageView trackIconImageView;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View rowView;
        Holder holder = new Holder();
        rowView = inflater.inflate(R.layout.song_list_items, null);
        holder.songNameTextView = (TextView) rowView.findViewById(R.id.songName);
        holder.artistNameTextView = (TextView) rowView.findViewById(R.id.artistNameTextView);
        holder.trackIconImageView = (ImageView) rowView.findViewById(R.id.trackIconImageView);

        holder.songNameTextView.setText(track_info.get(position).get(0));
        holder.artistNameTextView.setText(track_info.get(position).get(2));

        imageViews.add(position, holder.trackIconImageView);
        if(position < imageBitMaps.size()) {
            holder.trackIconImageView.setImageBitmap(imageBitMaps.get(position));
        }

        return rowView;
    }

    private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
        int position;
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        protected Bitmap doInBackground(String... urls) {
            HttpResponse response = null;
            HttpClient httpClient = new DefaultHttpClient();
            String albumpicture;
            Bitmap mIcon11 = null;
            position = Integer.valueOf(urls[1]);

            HttpGet httpPost = new HttpGet(urls[0]);
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("Accept", "application/json"));
            params.add(new BasicNameValuePair("Authorization Bearer ", token));

            try {
                response = httpClient.execute(httpPost);
                // writing response to log
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                try {
                    JSONObject jsonObject = new JSONObject(EntityUtils.toString(response.getEntity()));
                    albumpicture = jsonObject.getJSONObject("album").getJSONArray("images").getJSONObject(0).getString("url");
                    InputStream in = new java.net.URL(albumpicture).openStream();
                    mIcon11 = BitmapFactory.decodeStream(in);
                    mIcon11 = getResizedBitmap(mIcon11, 50, 50);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return mIcon11;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            imageViews.get(position).setImageBitmap(bitmap);
            imageBitMaps.add(position, bitmap);
            if(position < track_info.size() - 1) {
                downloadImageTask = new DownloadImageTask();
                downloadImageTask.execute("https://api.spotify.com/v1/tracks/" + track_info.get(downloadsCounter).get(1).replace("spotify:track:", ""), String.valueOf(downloadsCounter));
            }
            downloadsCounter++;

        }
    }

DownloadImageTask是我下载图像的地方,我首先在构造函数中调用它。

要点:
第一个imageView加载并填充,但其他的不会填充,除非我从那里滚动(向下滚动)然后再备份。

2 个答案:

答案 0 :(得分:0)

我们有很棒的开源库来处理图像下载和缓存 - Picasso Square

我们应该总是尝试使用现有的和经过验证的解决方案,而不是试图重新发明轮子。

答案 1 :(得分:0)

@Rockyfish,

您可以减少加载Images并自行管理网络电话的喧嚣。

您的加载图像逻辑可以被这样的一行代码替换。

Picasso.with(getApplicationContext()).load(image_url).into(holder.trackIconImageView);

where,

getApplicationContext() ===> is context which can be replaced with context you you are assigning to the `adapter` 

image_url =================> is the url to the imgae,

从保存在某个网址的图片中加载ImgaeView的过程由Picasso完成,因为你知道他是一位伟大的画家,所以让他去做。

添加Picasso库,将以下代码添加到build.gradle文件中的依赖项块,如下所示

compile 'com.squareup.picasso:picasso:2.5.2'

您可以使用picasso