0

I am trying to Implement Gallery App using Recycler view and Sub Sampling Gallery. Since my Image Count is around 850. When I try to load images into Gallery, the Gallery Lags.

here is my Recyclerview Adapter:-

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolders> {

private ArrayList<String> yeniliste;
private Context context;

public RecyclerViewAdapter(Context context, ArrayList<String> itemList) {
    this.yeniliste = itemList;
    this.context = context;
}

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

@Override
public void onBindViewHolder(final RecyclerViewHolders holder, final int position) {
    try {
        Bitmap bitmap = BitmapFactory.decodeFile(yeniliste.get(position));
        holder.countryPhoto.setImage(ImageSource.bitmap(bitmap).dimensions(50,50));
    }catch (Exception e){
        e.printStackTrace();
    }

    holder.countryPhoto.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(v.getContext(),GalleryFullImage.class);
            intent.putExtra("realid",String.valueOf(holder.getAdapterPosition()));
            v.getContext().startActivity(intent);
        }
    });
}

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


public static class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{

    public SubsamplingScaleImageView countryPhoto;

    public RecyclerViewHolders(View itemView) {
        super(itemView);
        countryPhoto = (SubsamplingScaleImageView)itemView.findViewById(R.id.country_photo);
    }

    @Override
    public void onClick(View view) {
        Toast.makeText(view.getContext(), "Clicked Country Position = " + getAdapterPosition(), Toast.LENGTH_SHORT).show();

    }

}

public void removeItem(int position)
{
    yeniliste.remove(position);
    notifyDataSetChanged();
}}
Tushar Pingale
  • 337
  • 2
  • 7
  • 18
  • 1
    this may be taking too long: "Bitmap bitmap = BitmapFactory.decodeFile(yeniliste.get(position));" Try using a library like picasso or glide. The main reason is that is being done in main the thread. If you do not want to use a library then you need to do that operation in a different thread – Leandro Ocampo Jul 25 '17 at 15:06
  • I tried Loading with picasso, But the images are not Loading – Tushar Pingale Jul 25 '17 at 15:10
  • Did you tried glide: https://stackoverflow.com/questions/34443171/load-image-from-sd-card-using-glide. You can check this in case of picasso: https://stackoverflow.com/questions/24097576/how-to-load-image-from-sd-card-using-picasso-library – Leandro Ocampo Jul 25 '17 at 15:11
  • But no matter what.. the reason is that operation about decoding to a bitmap is expensive, so you need to do that in a different thread. Those libraries do that for you in a clean way – Leandro Ocampo Jul 25 '17 at 15:13
  • String completePath = yeniliste.get(position); File file = new File(completePath); Uri imageUri = Uri.fromFile(file); Glide.with(context) .load(imageUri) .into(holder.countryPhoto); – Tushar Pingale Jul 25 '17 at 15:18
  • I tried as u Suggested using Glide, But no Images are showing – Tushar Pingale Jul 25 '17 at 15:18
  • Show me the path to that file please – Leandro Ocampo Jul 25 '17 at 15:22
  • D/Path: /storage/emulated/0/MyGallery/IMG-20170119-WA0007.jpg – Tushar Pingale Jul 25 '17 at 15:25
  • Try this option: String fileName = "1.jpg"; String completePath = Environment.getExternalStorageDirectory() + "/" + fileName; File file = new File(completePath); Uri imageUri = Uri.fromFile(file); – Leandro Ocampo Jul 25 '17 at 15:26
  • Also you may want to have a look at this: https://github.com/bumptech/glide/issues/760 – Leandro Ocampo Jul 25 '17 at 15:30
  • Are you shure that the delay comes from image loading and not from preloading the 800 file urls into the array? Is the gallery faster if you only have only 80 image-urls? if yes the problem is the array. if no the problem migth be image-preview caching or high image resolution – k3b Jul 25 '17 at 15:50

1 Answers1

0
Bitmap bitmap = BitmapFactory.decodeFile(yeniliste.get(position));

There are some problems in this call:

First, you are not downscaling the image when loading to memory. I would not be surprised if you start to get a lot of Out Of Memory exceptions thrown out by your app.

Second, you are loading the image in the UI thread, which is an expensive operation and will cause the lag you are experiencing: your app will not be able to render a new frame while it's loading the image from disk. You need to use a background thread to do the job. The most comon way to do this is to use an Async Task, one example is described here.

But the best option is to use an library to handle this for you. I really recommend Glide. It will already handle memory downscaling, background loading, cache for fast reloading, plus it has a really intuitive API.

This code:

Bitmap bitmap = BitmapFactory.decodeFile(yeniliste.get(position));
holder.countryPhoto.setImage(ImageSource.bitmap(bitmap).dimensions(50,50);

Will become:

GlideApp.with(context).load(eniliste.get(position)).override(50,50).centerCrop().into(new SimpleTarget<Bitmap>(50, 50) {
        @Override
        public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
         holder.countryPhoto.setImage(ImageSource.bitmap(bitmap));
        );

As you are not using a simple ImageView as the bitmap holder, you will need to use a custom target implementation.

I really recomend reading the docs or as questions about glide if you are having trouble implementing this.

Ian Medeiros
  • 1,746
  • 9
  • 24