1

I have three RecyclerViews, and all three are lagging in scroll. I have tried many things suggested on the internet, but nothing made my RecyclerView faster.

I have tried the solutions given below,

  1. RecyclerView laggy scrolling
  2. Extremely Laggy RecyclerView Performance
  3. Lags when RecyclerView scrolling

And some more. Some of them are not relevant. But still, it lags.

For the reference, below are the images for RecyclerView items.

There's no image here

The xml of the view (for the single chat bubble). It's almost same as WhatsApp.

<LinearLayout
    android:id="@+id/transactionOut"
    android:layout_width="@dimen/dp300"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:visibility="gone"
    android:layout_gravity="end"
    android:paddingStart="0dp"
    android:paddingLeft="0dp"
    android:paddingEnd="13dp"
    android:paddingRight="13dp"
    android:clickable="true"
    android:background="@drawable/outgoing_chat_bubble">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="start"
        android:minWidth="@dimen/dp100"
        android:orientation="horizontal"
        android:elevation="@dimen/general_margin_or_padding_very_small"
        android:padding="@dimen/dp10">

        <ImageView
            android:id="@+id/transactionImageOut"
            android:layout_margin="@dimen/dp4"
            android:layout_width="@dimen/size_transaction"
            android:layout_height="@dimen/size_transaction"
            android:padding="3dp"
            android:visibility="gone"
            android:src="@drawable/ic_transaction_indication_sent"
            android:layout_gravity="center_vertical"
            android:contentDescription="@string/payment_sent"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="4dp"
            android:layout_marginRight="4dp"
            android:gravity="center"
            android:textSize="@dimen/general_for_all"
            android:text="–"
            android:textColor="@color/app_font_detail_color"/>

        <style.views.CustomTextView
            android:id="@+id/transactionAmountOut"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/progress_loading"
            android:textColor="@color/app_font_detail_color"
            android:layout_marginLeft="@dimen/dp4"
            android:layout_marginStart="@dimen/dp4"
            android:ellipsize="end"
            android:maxLines="1"
            android:textSize="@dimen/general_for_all"
            appUI:font="@string/appNormalFontName"/>

    </LinearLayout>

    <View
        android:id="@+id/separatorMessageOut"
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:visibility="gone"
        android:layout_marginStart="@dimen/general_margin_or_padding_very_small"
        android:layout_marginEnd="@dimen/general_margin_or_padding_very_small"
        android:layout_marginRight="@dimen/general_margin_or_padding_very_small"
        android:layout_marginLeft="@dimen/general_margin_or_padding_very_small"
        android:background="@color/app_font_detail_color"/>

    <LinearLayout
        android:id="@+id/layoutMessageOut"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="top"
        android:visibility="gone"
        android:paddingTop="@dimen/general_margin_or_padding_very_small"
        android:paddingBottom="@dimen/general_margin_or_padding_very_small">

        <ImageView
            android:layout_width="@dimen/size_extra_icon"
            android:layout_height="@dimen/size_extra_icon"
            android:layout_marginTop="@dimen/icon_margin_top"
            android:src="@drawable/ic_sms"
            android:layout_marginStart="@dimen/general_margin_or_padding_small"
            android:layout_marginLeft="@dimen/general_margin_or_padding_small"
            android:visibility="visible"
            android:contentDescription="@string/design"/>


        <TextView
            android:id="@+id/textMessageOut"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/general_margin_or_padding_very_small"
            android:layout_marginLeft="@dimen/general_margin_or_padding_very_small"
            android:textColor="@color/app_font_detail_color"
            android:text="Text message"/>

    </LinearLayout>

    <View
        android:id="@+id/separatorNoteOut"
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:visibility="gone"
        android:layout_marginStart="@dimen/general_margin_or_padding_very_small"
        android:layout_marginEnd="@dimen/general_margin_or_padding_very_small"
        android:layout_marginRight="@dimen/general_margin_or_padding_very_small"
        android:layout_marginLeft="@dimen/general_margin_or_padding_very_small"
        android:background="@color/app_font_detail_color"/>

    <LinearLayout
        android:id="@+id/layoutNoteOut"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="top"
        android:visibility="gone"
        android:paddingTop="@dimen/general_margin_or_padding_very_small"
        android:paddingBottom="@dimen/general_margin_or_padding_very_small">

        <ImageView
            android:layout_width="@dimen/size_extra_icon"
            android:layout_height="@dimen/size_extra_icon"
            android:layout_marginTop="@dimen/icon_margin_top"
            android:src="@drawable/ic_notes"
            android:layout_marginStart="@dimen/general_margin_or_padding_small"
            android:layout_marginLeft="@dimen/general_margin_or_padding_small"
            android:visibility="visible"
            android:contentDescription="@string/design"/>


        <TextView
            android:id="@+id/textNoteOut"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/general_margin_or_padding_very_small"
            android:layout_marginLeft="@dimen/general_margin_or_padding_very_small"
            android:textColor="@color/app_font_detail_color"
            android:text="Text note"/>

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/app_font_detail_color"
        android:layout_marginStart="@dimen/general_margin_or_padding_very_small"
        android:layout_marginEnd="@dimen/general_margin_or_padding_very_small"
        android:layout_marginRight="@dimen/general_margin_or_padding_very_small"
        android:layout_marginLeft="@dimen/general_margin_or_padding_very_small"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="@dimen/dp6">

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="start|center_vertical">

            <style.views.CircleImageView
                android:id="@+id/bankLogoOut"
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:layout_gravity="center_vertical"
                android:src="@drawable/placeholder_default"
                appUI:circular_border_color="@color/profile_border_color"
                appUI:circular_border_width="@dimen/dp1" />

            <TextView
                android:id="@+id/bankNameOut"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/general_margin_or_padding_very_small"
                android:layout_marginLeft="@dimen/general_margin_or_padding_very_small"
                android:maxLines="1"
                android:ellipsize="end"
                android:text="@string/progress_loading"
                android:textSize="@dimen/small_size" />

        </LinearLayout>

        <ImageView
            android:id="@+id/showDetailImageOut"
            android:layout_width="0dp"
            android:layout_weight="0.5"
            android:layout_height="wrap_content"
            android:layout_marginRight="@dimen/dp4"
            android:layout_marginEnd="@dimen/dp4"
            android:src="@drawable/ic_transaction_more"
            android:contentDescription="@string/more"/>

        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1">

            <ImageView
                android:id="@+id/messageStatusImageOut"
                android:layout_width="@dimen/size_transaction"
                android:layout_height="@dimen/size_transaction"
                android:layout_centerVertical="true"
                android:src="@drawable/ic_pending"
                android:layout_marginStart="@dimen/general_margin_or_padding_small"
                android:layout_marginLeft="@dimen/general_margin_or_padding_small"
                android:visibility="visible"
                android:contentDescription="@string/design"
                android:layout_alignParentEnd="true"
                android:layout_alignParentRight="true"/>

            <style.views.CustomTextView
                android:id="@+id/transactionDatetimeOut"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:gravity="end"
                android:text="@string/account"
                android:textColor="@color/app_font_detail_color"
                android:textSize="@dimen/date_time_stamp"
                android:layout_toLeftOf="@+id/messageStatusImageOut"
                android:layout_toStartOf="@+id/messageStatusImageOut" />

        </RelativeLayout>


    </LinearLayout>

</LinearLayout>

Here is it's adapter

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    holder.setIsRecyclable(false);
    if (holder instanceof HeaderViewHolder) {
        HeaderViewHolder transactionViewHolder = (HeaderViewHolder) holder;
        String getTodayDate = (String) filteredList.get(position);
        transactionViewHolder.setDate(DateUtility.getFormattedDate(getTodayDate));

    } else if (holder instanceof MainViewHolder) {
        MainViewHolder viewHolder = (MainViewHolder) holder;
        try {
            final History history = (History) filteredList.get(position);
            viewHolder.setTransaction(history, mContext);
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

And the setTransaction method of ViewHolder

private void setTransaction(final History history, final Context context){
    String myId = new Session(context).getStringForKey(Session.prIdKey);
    if(history.getTo().equals(history.getFrom())) {

        transactionSelf.setVisibility(View.VISIBLE);
        transactionOut.setVisibility(View.GONE);
        transactionIn.setVisibility(View.GONE);

        transactionAmountSelf.setText(Utils.parseIntoPKR(history.getAmount()));
        transactionDateTimeSelf.setText(DateUtility.getTimeFromEpoch(history.getEpoch()));

        messageStatusImageSelf.setVisibility(View.VISIBLE);
        switch (history.getStatus()) {
            case Constants.STATUS_PENDING:
                messageStatusImageSelf.setImageResource(R.drawable.ic_pending);
                break;
            case Constants.STATUS_FAILED:
                messageStatusImageSelf.setImageResource(R.drawable.ic_transaction_status_blocked);
                break;
            default:
                messageStatusImageSelf.setImageResource(R.drawable.ic_transaction_status_done);
                break;
        }

        LinkedBank associatedBank = history.getSenderBank();
        bankNameSelf.setText(associatedBank.fetchAbbreviationAndAccountNumber());

        if(history.getReceiverNotes() != null && history.getReceiverNotes().length() > 0) {
            separatorNoteSelf.setVisibility(View.VISIBLE);
            layoutNoteSelf.setVisibility(View.VISIBLE);
            textNoteSelf.setText(history.getReceiverNotes());
        } else if(history.getSenderNotes() != null && history.getSenderNotes().length() > 0) {
            separatorNoteSelf.setVisibility(View.VISIBLE);
            layoutNoteSelf.setVisibility(View.VISIBLE);
            textNoteSelf.setText(history.getSenderNotes());
        }

        transactionSelf.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((OnIndividualTransactionSelection) context).onTransactionSelected(history);
            }
        });


    } else if(history.getFrom().equals(myId)) {
        //from my number -> cash out
        transactionOut.setVisibility(View.VISIBLE);
        transactionIn.setVisibility(View.GONE);
        transactionSelf.setVisibility(View.GONE);

        if(history.getMessage() != null && history.getMessage().length() > 0) {
            separatorMessageOut.setVisibility(View.VISIBLE);
            layoutMessageOut.setVisibility(View.VISIBLE);
            textMessageOut.setText(history.getMessage());
        }

        if(history.getSenderNotes() != null && history.getSenderNotes().length() > 0) {
            separatorNoteOut.setVisibility(View.VISIBLE);
            layoutNoteOut.setVisibility(View.VISIBLE);
            textNoteOut.setText(history.getSenderNotes());
        }

        messageStatusImageOut.setVisibility(View.VISIBLE);
        switch (history.getStatus()) {
            case Constants.STATUS_PENDING:
                messageStatusImageOut.setImageResource(R.drawable.ic_pending);
                break;
            case Constants.STATUS_FAILED:
                messageStatusImageOut.setImageResource(R.drawable.ic_transaction_status_blocked);
                break;
            default:
                messageStatusImageOut.setImageResource(R.drawable.ic_transaction_status_done);
                break;
        }


        transactionAmountOut.setText(Utils.parseIntoPKR(history.getAmount()));
        transactionDatetimeOut.setText(DateUtility.getTimeFromEpoch(history.getEpoch()));

        LinkedBank associatedBank = history.getSenderBank();
        bankNameOut.setText(associatedBank.fetchAbbreviationAndAccountNumber());
        Picasso.with(context).load(associatedBank.getBankLogo()).placeholder(R.drawable.placeholder_default).error(R.drawable.placeholder_default).into(bankLogoOut);


        transactionOut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((OnIndividualTransactionSelection) context).onTransactionSelected(history);
            }
        });

    } else if(history.getTo().equals(myId)) {
        transactionIn.setVisibility(View.VISIBLE);
        transactionOut.setVisibility(View.GONE);
        transactionSelf.setVisibility(View.GONE);

        if(history.getMessage() != null && history.getMessage().length() > 0) {
            separatorMessageIn.setVisibility(View.VISIBLE);
            layoutMessageIn.setVisibility(View.VISIBLE);
            textMessageIn.setText(history.getMessage());
        }

        if(history.getReceiverNotes() != null && history.getReceiverNotes().length() > 0) {
            separatorNoteIn.setVisibility(View.VISIBLE);
            layoutNoteIn.setVisibility(View.VISIBLE);
            textNoteIn.setText(history.getReceiverNotes());
        }


        transactionAmountIn.setText(Utils.parseIntoPKR(history.getAmount()));
        transactionDatetimeIn.setText(DateUtility.getTimeFromEpoch(history.getEpoch()));

        LinkedBank associatedBank = history.getReceiverBank();
        bankNameIn.setText(associatedBank.fetchAbbreviationAndAccountNumber());
        Picasso.with(context).load(associatedBank.getBankLogo()).placeholder(R.drawable.placeholder_default).error(R.drawable.placeholder_default).into(bankLogoIn);

        transactionIn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((OnIndividualTransactionSelection) context).onTransactionSelected(history);

            }
        });

    }

}

It's answer may help me to optimize the other two RecyclerViews as well. Any help is highly appreciated.

Waqas Ahmed Ansari
  • 1,590
  • 13
  • 28

1 Answers1

0

Two quick tips

1) You might want to cut down on a lots o processing while it's still scrolling. This will improve scrolling performance substantially

2) You might want to relook at this and similar 'new' later, allocating on every bind will slow down your scroll.

 String myId = new Session(context).getStringForKey(Session.prIdKey);
Mark
  • 3,373
  • 2
  • 21
  • 34
  • Thank you for the answer, but I need suggestions what and how to cut down? I have already gone through the code several times and I couldn't find anything unnecessary. This is actually to show chat bubble and there are three types of it, plus the date header - total 4 views in a `RecyclerView`, what would you suggest? – Waqas Ahmed Ansari Aug 24 '17 at 04:28