RecyclerView重新加载图像

时间:2016-12-31 01:05:03

标签: android android-recyclerview

我创建了一个小应用程序,它连接到OMDB并使用它的API来获取电影数据。 正如您在下面的电影中看到的,如果我滚动得非常快,我可以看到重新填充的图像。调试显示它们确实被重新下载。我应该提一下,我不保留文件的任何物理副本。

这被认为是正常行为还是我遗漏了什么?

链接: https://youtu.be/2dO3XwGd5g8

RecyclerView类

package com.example.themoviekeeper.ui;

import android.app.Activity;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.themoviekeeper.R;
import com.example.themoviekeeper.db.MyMovie;
import com.example.themoviekeeper.networking.Task_DownloadImage;

import java.util.ArrayList;

/**
 * Created by Xcalibur on 30/12/2016.
 */

public class RecyclerViewAdapter_Search extends RecyclerView.Adapter<RecyclerViewAdapter_Search.MyViewHolder>{

    private ArrayList<MyMovie> _list;
    private Activity _activity;
    private LayoutInflater inflater;

    public RecyclerViewAdapter_Search(ArrayList<MyMovie> list, Activity activity) {

        _list = list;
        _activity = activity;

        inflater = LayoutInflater.from(_activity);
    }

    @Override
    public RecyclerViewAdapter_Search.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = inflater.inflate(R.layout.view_search, parent, false);

        MyViewHolder holder = new MyViewHolder(view);

        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        String year = _list.get(position).getYear();
        String title = _list.get(position).getTitle();
        String type = _list.get(position).getType();
        String poster = _list.get(position).getPoster();

        holder.tv_year.setText(year);
        holder.tv_type.setText(type);
        holder.tv_title.setText(title);

        Task_DownloadImage dlImage = new Task_DownloadImage(_activity,holder);
        String [] imageUrl ={poster};
        dlImage.execute(imageUrl);


    }


    @Override
    public int getItemCount() {
        return _list.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {

        TextView tv_year,tv_title,tv_type;
        public ImageView iv_poster;

        public MyViewHolder(View itemView) {
            super(itemView);

            tv_title = (TextView)itemView.findViewById(R.id.tv_title_searchview);
            tv_type = (TextView)itemView.findViewById(R.id.tv_type_searchview);
            tv_year = (TextView)itemView.findViewById(R.id.tv_year_searchview);
            iv_poster = (ImageView)itemView.findViewById(R.id.iv_searchview);

        }

    }


}

执行实际图像下载的Asynctask

package com.example.themoviekeeper.networking;

import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.themoviekeeper.R;
import com.example.themoviekeeper.ui.RecyclerViewAdapter_Search;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by Xcalibur on 30/12/2016.
 */

public class Task_DownloadImage extends AsyncTask<String, Integer,Bitmap>
{

    private Activity mActivity;
    private ProgressDialog mDialog;
    private RecyclerViewAdapter_Search.MyViewHolder mHolder;

    public Task_DownloadImage(Activity activity, RecyclerViewAdapter_Search.MyViewHolder holder) {

        mHolder = holder;
        mActivity = activity;
        mDialog = new ProgressDialog(mActivity);
    }

    protected Bitmap doInBackground(String... urls) {
        Log.d("doInBackground", "starting download of image");
        Bitmap image = downloadImage(urls[0]);
        return image;
    }

    protected void onPreExecute() {
        //ImageView imageView = (ImageView) mActivity.findViewById(R.id.imageView);
        //imageView.setImageBitmap(null);
        // Reset the progress bar
//        mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//        mDialog.setCancelable(true);
//        mDialog.setMessage("Loading...");
//        mDialog.setProgress(0);
        //TextView errorMsg = (TextView) mActivity.findViewById(R.id.textView);
        //errorMsg.setVisibility(View.INVISIBLE);
    }

    protected void onProgressUpdate(Integer... progress) {
//        mDialog.show();
//        mDialog.setProgress(progress[0]);
    }

    protected void onPostExecute(Bitmap result) {

        if (result != null) {
            mHolder.iv_poster.setImageBitmap(result);
//            ImageView imageView = (ImageView)mActivity.findViewById(R.id.imageView);
//            imageView.setImageBitmap(result);
        }
        else {
//            TextView errorMsg = (TextView)mActivity.findViewById(R.id.textView);
//            errorMsg.setVisibility(View.VISIBLE);
//            errorMsg.setText("Problem downloading image. Try again later");
        }
        // Close the progress dialog
        //mDialog.dismiss();
    }

    private Bitmap downloadImage(String urlString) {
        URL url;
        try {
            url = new URL(urlString);
            HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
            InputStream is = httpCon.getInputStream();
            int fileLength = httpCon.getContentLength();
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int nRead, totalBytesRead = 0;
            byte[] data = new byte[2048];
            mDialog.setMax(fileLength);
            // Read the image bytes in chunks of 2048 bytes
            while ((nRead = is.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, nRead);
                totalBytesRead += nRead;
                publishProgress(totalBytesRead);
            }
            buffer.flush();
            byte[] image = buffer.toByteArray();
            Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

1 个答案:

答案 0 :(得分:1)

是的,根据您的代码,这是预期的行为。 Android不会自动缓存来自HTTP请求的下载内容,因此每次滚动新回收的视图时都会重新下载其图像。

我建议您在代码中使用像PicassoGlide这样的图像加载库,因为它们会自动缓存下载的图像,并针对在recyclerviews中使用进行了优化。