Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recycler View Laggy on Scroll up and down

So I looked at hundreds of questions for the past day, reading everything, and this is what I gathered...

One person said add this:

homeRecyclerView.setHasFixedSize(true);

which I tried did nothing, for the question on scrolling down or up does it lag? To both.

It is a drawable and I was using Picasso (drawable because I want to test the view before doing a server call) So someone said maybe the caching system is affecting it, removed Picasso and the imageviews by default have the image but still lags...

Here is the declaration in the home activity:

homeRecyclerView = (RecyclerView) findViewById(R.id.home_recycler_view);
            homeRecyclerView.setHasFixedSize(true);
  homeAdapter = new HomeAdapter(this, homeList);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        homeRecyclerView.setLayoutManager(mLayoutManager);
        homeRecyclerView.setItemAnimator(new DefaultItemAnimator());

        homeRecyclerView.setAdapter(homeAdapter);

  public interface ClickListener {
        void onClick(View view, int position);

        void onLongClick(View view, int position);
    }

    public static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {

        private GestureDetector gestureDetector;
        private MainHome.ClickListener clickListener;

        public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final MainHome.ClickListener clickListener) {
            this.clickListener = clickListener;
            gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    return true;
                }

                @Override
                public void onLongPress(MotionEvent e) {
                    View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                    if (child != null && clickListener != null) {
                        clickListener.onLongClick(child, recyclerView.getChildPosition(child));
                    }
                }
            });
        }

        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {

            View child = rv.findChildViewUnder(e.getX(), e.getY());
            if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
                clickListener.onClick(child, rv.getChildPosition(child));
            }
            return false;
        }

        @Override
        public void onTouchEvent(RecyclerView rv, MotionEvent e) {
        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

        }
    }

This is the home adapter:

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

    private List<items> items;
    private Context context;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView text;
        public ImageView pic;

        public MyViewHolder(View view) {
            super(view);
           text = (TextView) view.findViewById(R.id.text);

            pic = (ImageView) view.findViewById(R.id.pic);
        }
        }

        public HomeAdapter(Context mContext, List<items> items) {
            context = mContext;
            this.items = items;
        }

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.home_item, parent, false);

            return new MyViewHolder(itemView);
        }

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

            Typeface myTypeface = Typeface.createFromAsset(context.getAssets(), "font1.ttf");
            Typeface myTypefaceItalic = Typeface.createFromAsset(context.getAssets(), "font2.ttf");
            Typeface myTypefaceBold = Typeface.createFromAsset(context.getAssets(), "font3.ttf");

            Item item = items.get(position);


            holder.text.setTypeface(myTypefaceBold);


Picasso.with(context).load(R.drawable.robot).into(holder.pic);
        }

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


}

Anyone who can please point out what can be possibly causing this laggy scrolling issue or suggestions. I switched from a listview with a holder in the adapter to recycler view hearing that it is smoother and better... but it seems to be worse at scrolling...

like image 729
Lion789 Avatar asked Dec 14 '22 07:12

Lion789


2 Answers

Your problem is with

    Typeface myTypeface = Typeface.createFromAsset(context.getAssets(), "Lato_Regular.ttf");
        Typeface myTypefaceItalic = Typeface.createFromAsset(context.getAssets(), "Lato_Italic.ttf");
        Typeface myTypefaceBold = Typeface.createFromAsset(context.getAssets(), "Lato_Bold.ttf");

You are initialising it each time in bind view. createFromAsset takes some memory and processing power. Do it each time your bind view is called and you have a scroll lag.

I would suggest moving this code to your activity and passing it in your recycler view constructor.

Try this and let me know if it solves your problem.

like image 171
Ragesh Ramesh Avatar answered Feb 10 '23 03:02

Ragesh Ramesh


I think your problem is to create the Typeface objects every time on onBindViewHolder(). Create then on the constructor and keep a reference to them.

Also, I would attach these Typefaces on onCreateViewHolder() instead of onBindViewHolder(), since they don't need to be changed when recycled.

I think this answer can help you too.

like image 33
Alan Wink Avatar answered Feb 10 '23 05:02

Alan Wink