Android将缓存的图像加载到RecyclerView重新排列网格中

时间:2016-02-02 10:56:01

标签: android grid android-recyclerview

我在我的项目中使用Recycler View。我正在生成类似pinterest的多列网格。一切正常。我的应用程序从externalstorage加载数据(图像也是如此)。当加载在UI线程中时,滚动性能非常差。所以我决定创建AsyncTask来从路径加载图像,这是在向下滚动时的意思。当我再次向上滚动时,我遇到了问题,因为重新创建单元格正在弄乱网格布局。它正在重新排列,对用户来说可能很差。在内存中缓存图像(它们的很多)并不好我想,są或许可以选择为每个单元存储有关ImageView大小的信息并保留它以供重用?

我的RecyclerView布局适配器如下所示:

public class MainGridAdapter extends RecyclerView.Adapter<ArticleViewHolder> {
private List<Article> articleList;
private Context context;

public MainGridAdapter(Context context, List<Article> articleList) {
    this.articleList = articleList;
    this.context = context;
}

@Override
public ArticleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.article_cell, null);
    ArticleViewHolder avc = new ArticleViewHolder(layoutView);
    return avc;
}

@Override
public void onBindViewHolder(ArticleViewHolder holder, final int position) {
    Typeface StagMedium = Typeface.createFromAsset(context.getAssets(), "fonts/Stag-Medium.otf");
    holder.articleTitle.setText(articleList.get(position).getTitle());
    holder.articleTitle.setTypeface(StagMedium);
    //Wczytuję obrazek
    Log.v("DDD", articleList.get(position).getTitle());
    Log.v("DDD", String.valueOf(articleList.get(position).getId()));


    //TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, articleList.get(position).getCover_height());
    //holder.container.setLayoutParams(params);
    BitmapWorkerTask task = new BitmapWorkerTask(holder.articleImage);
    task.execute(articleList.get(position).getCover_local_path());
    /*
    File file = new File(articleList.get(position).getCover_local_path());
    if(file.exists()) {
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), bmOptions);
        holder.articleImage.setImageBitmap(bitmap);
    }
    */

    //Jeżeli materiał to video to pokazuję ikonkę
    Log.v("DDD", "Type: " + articleList.get(position).getType());
    if(articleList.get(position).getType().equals("article")) {
        Log.v("DDD", "Article");
        holder.articleVideoIcon.setImageResource(android.R.color.transparent);
    } else {
        Log.v("DDD", "Video");
        holder.articleVideoIcon.setImageResource(R.drawable.play);
    }


    holder.container.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.v("DDD", "Klikłem sobie na pozycję: " + String.valueOf(position));
            Intent intent= new Intent(context,SingleArticle.class);
            Log.v("DDD", String.valueOf(articleList.get(position).getId()));
            intent.putExtra("articleId", articleList.get(position).getId());
            context.startActivity(intent);
        }
    });


}

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

class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private String path  = "";

    public BitmapWorkerTask(ImageView imageView) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    // Decode image in background.
    @Override
    protected Bitmap doInBackground(String... params) {
        path = params[0];
        File file = new File(path);
        if (file.exists()) {
            BitmapFactory.Options bmOptions = new BitmapFactory.Options();
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(),bmOptions);
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();

            //Bitmap resized_bitmap = Bitmap.createScaledBitmap(bitmap, Math.round(width / 2), Math.round(height / 2), false);
            //return resized_bitmap;
            return bitmap;
        } else {
            return null;
        }
    }

    // Once complete, see if ImageView is still around and set bitmap.
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);

            }
        }
    }
}
}

1 个答案:

答案 0 :(得分:0)

好的,我已经解决了我的问题。问题是API和数据结构也是我的代码,所以我开始存储SQLite thimbs大小。通过这种方式,我可以在“OnBindViewHolder”中设置单元格大小,如下所示:

 TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT,         articleList.get(position).getCover_height());
 holder.container.setLayoutParams(params);

您也可以下载Bitmap,并在List或数组中存储高度并执行相同的操作。容器的当前高度应该转换为dp,但它的工作方式就像一个魅力。解决了浮动物品的问题。谢谢你帮忙:)