user1361491
user1361491

Reputation:

Images in RecyclerView

I am using RecyclerView in Android and I am having some trouble with images.

I would like to display a list of the images in a particular folder with their path names.

So this is my row.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

        <TextView
            android:id="@+id/my_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="test" />

        <ImageView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true" />

</LinearLayout>

In my adapter, I use this code to set the image of a row:

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.mTextView.setText(mDataset[position]);
    holder.mImageView.setImageURI(Uri.parse("file://" + mMediaStorageDir.getPath() + "/" + mDataset[position]));
}

The images load fine, but when I scroll down the whole app becomes very slow.

This doesn't happen when I load a small drawable instead. Is it because the pictures are too big?

Upvotes: 12

Views: 100776

Answers (4)

Usama Zafar
Usama Zafar

Reputation: 97

If you have a list of Data containing the image Uri's in your main Activity (Where your adapter is called) such as in MainActivity.java

contacts.add(new Data(R.drawable.ic_launcher_foreground, "Usama Zafar" , 400));

. . .

then in your Adapter (MainAdapter.java)

inside the onBindViewHolder() method you can write as

@Override
public void onBindViewHolder(@NonNull MainAdapter.MyViewHolder holder, final int 
position) {

    final Data currentItem =ls.get(position);
    
    holder.img.setImageDrawable(c.getDrawable(currentItem.getImage()));
    holder.name.setText(currentItem.getName());
    holder.amount.setText(currentItem.getAmount());
}

Upvotes: 0

Sergey Shustikov
Sergey Shustikov

Reputation: 15821

Yes. I think it's too big.

You need load firstly your images(track for free memory) and after that use him.

Not necessarily use Picasso. But you can use it.

I recommend to you read the

And example :

ItemData.java

package com.shustikov.android;

public class ItemData {

    private String title;
    private int imageUrl;

    public ItemData(String title,int imageUrl){

        this.title = title;
        this.imageUrl = imageUrl;
    }

    public String getTitle() {
        return title;
    }

    public int getImageUrl() {
       return imageUrl;
    }
}

RecyclerViewExampleAdapter.java

package com.shustikov.android;

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;

public class RecyclerViewExampleAdapter extends RecyclerView.Adapter<RecyclerViewExampleAdapter.ViewHolder> {
    private ItemData[] itemsData;

    public RecyclerViewExampleAdapter(ItemData[] itemsData) {
        this.itemsData = itemsData;
    }

    @Override
    public RecyclerViewExampleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        View itemLayoutView = LayoutInflater.from(parent.getContext())
                               .inflate(R.layout.item_layout, null);

        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {

        viewHolder.txtViewTitle.setText(itemsData[position].getTitle());
        viewHolder.imgViewIcon.setImageResource(itemsData[position].getImageUrl());
     }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        public TextView txtViewTitle;
        public ImageView imgViewIcon;

        public ViewHolder(View itemLayoutView) {
            super(itemLayoutView);
            txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title);
            imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
        }
    }


    @Override
    public int getItemCount() {
        return itemsData.length;
    }
}

Upvotes: 19

Shubhdeep Singh
Shubhdeep Singh

Reputation: 407

It takes time to mold the code using caching method and loading images before the fragment is displayed. An easy approach would be to use the Picasso Library. I myself used Picasso and now images load quite fast as I scroll.

Here is my code:

public void bindPhoto(Photo photo) {
    mPhoto = photo;
    mPhotoFile=PhotoLab.get(getActivity()).getPhotoFile(mPhoto);
    Uri uri=Uri.fromFile(mPhotoFile);

    if(mPhotoFile==null || !mPhotoFile.exists()){
        int imgdrawable=R.drawable.ic_action_name3;
        mThumbnail.setImageDrawable(getResources().getDrawable(imgdrawable));
    } else {
        Picasso.with(getActivity()).load(uri).fit().into(mThumbnail);
    }


    mTitleTextView.setText(mPhoto.getTitle());
    String dateFormat = "EEE, MMM dd";
    dateString = DateFormat.format(dateFormat, mPhoto.getDate()).toString();
    mDateTextView.setText(dateString);
}

Upvotes: 1

user468311
user468311

Reputation:

You're loading your images on UI thread, that's the problem. Loading file from disk or network takes some time. You can achieve the same, but using Picasso library. Please refer here.

Upvotes: 3

Related Questions