Nested Recycler view is laggy while scrolling for the first time

1.1k Views Asked by At

Here, I have two recyclerview that has parentRecyclerViewAdapter and childRecyclerViewAdapter. Parent adapter has LinearLayoutManager.VERTICAL layout manager whereas Clild adapter has GridLayoutManager(mContext, 2) layout manager with itemDecoration.

When scrolling for the first time the RecyclerView scrolling is laggy and once the data is viewed the scrolling is smooth. Until the app instance is not completely removed the scrolling will be smooth and when the app reinitiate the scrolling is laggy again.

Please help me out to figure out this BUG!!

ParentRecyclerViewAdapter

public class RecyclerViewDataAdapter extends RecyclerView.Adapter<RecyclerViewDataAdapter.ItemRowHolder> {

    private ArrayList<SectionDataModel> dataList;
    private Context mContext;
    private RecyclerListItemClick onListClick;

    public RecyclerViewDataAdapter(Context context, ArrayList<SectionDataModel> dataList) {
        this.dataList = dataList;
        this.mContext = context;
        onListClick = (RecyclerListItemClick) context;

    }

    @Override
    public ItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        return new ItemRowHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_row_template_section, null));

    }

    @Override
    public void onBindViewHolder(ItemRowHolder itemRowHolder, int i) {

        ArrayList<SingleTemplateModel> templateModelArrayList = dataList.get(i).getTemplateModelArrayList();
        String sectionName = dataList.get(i).getHeaderTitle();

        itemRowHolder.itemTitle.setText(sectionName);
        TemplateChooserAdapter itemListDataAdapter = new TemplateChooserAdapter(mContext, templateModelArrayList , dataList.get(i).getHeaderTitle());

        itemRowHolder.recycler_view_list.setAdapter(itemListDataAdapter);

    }

    @Override
    public int getItemCount() {
        return (null != dataList ? dataList.size() : 0);
    }

    public class ItemRowHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private TextView itemTitle;
        private RecyclerView recycler_view_list;

        private ItemRowHolder(View view) {
            super(view);

            this.itemTitle = view.findViewById(R.id.itemTitle);
            this.recycler_view_list = view.findViewById(R.id.recycler_view_list);
            this.recycler_view_list.setOnClickListener(this);
            this.recycler_view_list.setHasFixedSize(true);
            this.recycler_view_list.setLayoutManager(new GridLayoutManager(mContext, 2));
            this.recycler_view_list.addItemDecoration(new SpacesItemDecoration(2 , 25 , false));

        }

        @Override
        public void onClick(View v) {

        onListClick.onRecyclerItemClicked(dataList.get(getAdapterPosition()).getHeaderTitle());

        }
    }

}

ChildRecyclerAdapter

public class TemplateChooserAdapter extends RecyclerView.Adapter<TemplateChooserAdapter.ViewHolder> {

    private static final String TAG = TemplateChooserAdapter.class.getSimpleName();
    private Context context;
    private ArrayList<SingleTemplateModel> templateModelArrayList;
    private OnTemplatesListClicked onListClick;

    public TemplateChooserAdapter(Context context, ArrayList<SingleTemplateModel> templateModelArrayList, String sectionName) {
        this.context = context;
        this.templateModelArrayList = templateModelArrayList;
        onListClick = (OnTemplatesListClicked) context;
        AppUtils.showLog(TAG, "CorporateUserAdapter");

    }

    @Override
    public TemplateChooserAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(
                LayoutInflater.from(parent.getContext()).inflate(R.layout.single_row_template_chooser, parent, false)
        );
    }

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

        holder.templateView.setImageResource(templateModelArrayList.get(position).getImage());

    }

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

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

        ImageView templateView;

        public ViewHolder(View itemView) {
            super(itemView);
            templateView = itemView.findViewById(R.id.template_view);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {

            templateModelArrayList.get(getAdapterPosition()).setShowIndicator(true);
            onListClick.onTemplateClick(templateModelArrayList.get(getAdapterPosition())); // TODO send model when item clicked

        }
    }
}

Activity.java

private void recyclerViewJob() {

    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
    RecyclerViewDataAdapter adapter = new RecyclerViewDataAdapter(this, allSampleData);
    recyclerView.setAdapter(adapter);

}

SectionDataModel.java

public class SectionDataModel {


    private String headerTitle;
    private ArrayList<SingleTemplateModel> templateModelArrayList;


    public SectionDataModel() {

    }

    public SectionDataModel(String headerTitle, ArrayList<SingleTemplateModel> templateModelArrayList) {
        this.headerTitle = headerTitle;
        this.templateModelArrayList = templateModelArrayList;
    }


    public String getHeaderTitle() {
        return headerTitle;
    }

    public void setHeaderTitle(String headerTitle) {
        this.headerTitle = headerTitle;
    }

    public ArrayList<SingleTemplateModel> getTemplateModelArrayList() {
        return templateModelArrayList;
    }

    public void setTemplateModelArrayList(ArrayList<SingleTemplateModel> templateModelArrayList) {
        this.templateModelArrayList = templateModelArrayList;
    }

}

SingleTemplateModel.java

public class SingleTemplateModel {

    private String title;
    private String skuName;
    private int image;
    private boolean showIndicator;

    public SingleTemplateModel(String title, String skuName, int image, boolean showIndicator) {
        this.title = title;
        this.skuName = skuName;
        this.image = image;
        this.showIndicator = showIndicator;
    }

    public String getSkuName() {
        return skuName;
    }

    public void setSkuName(String skuName) {
        this.skuName = skuName;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    public boolean isShowIndicator() {
        return showIndicator;
    }

    public void setShowIndicator(boolean showIndicator) {
        this.showIndicator = showIndicator;
    }
}

single_row_template_section.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="30dp"
    android:clickable="true"
    android:focusable="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


        <TextView
            android:id="@+id/itemTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:layout_gravity="center_vertical"
            android:text="Sample title"
            android:textColor="@color/white"
            android:textSize="20sp"
            android:textStyle="bold"
            android:paddingLeft="5dp"
            android:paddingBottom="10dp"/>


    </RelativeLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:orientation="horizontal" />


</LinearLayout>

single_row_template_chooser.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="280dp"
    card_view:cardElevation="6dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/template_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="fitXY"
            android:src="@mipmap/model_9" />

    </RelativeLayout>

</android.support.v7.widget.CardView>
1

There are 1 best solutions below

6
On

I think you can try to lazy load your images from resources. There are libraries like Picasso or Glide that will help you with that.

So it may look like this:

Picasso:

import com.squareup.picasso.Picasso;
...

public class TemplateChooserAdapter extends RecyclerView.Adapter<TemplateChooserAdapter.ViewHolder> {
...

    @Override
   public void onBindViewHolder(final ViewHolder holder, int position) {
      Picasso.with(holder.itemView.getContext()).load(templateModelArrayList.get(position).getImage()).into(holder.templateView);
   }
...

}