I'm developing a search contact feature, in that screen, there is a RecyclerView inside NestedScrolView (fillViewport = true).
Screen design: (This design is accepted by customer, I can't change it)
After loading all contacts of current device into an ArrayList, the search results are filtered from this array.
There is several cases that make the app very laggy:
1. When user type an input that have no result, then user clear search, I have to show all results again. The NestedScrollView has to render UI for all items of RecyclerView (for example: 300 items).
2. When the quantity of results has many changes (for example, from 1 to 300 items). The NestedScrollView has to render UI for a lot of items of RecyclerView
I know this design breaks recycling technique of RecyclerView, but I can't change it.
What I tried:
recyclerView.setNestedScrollingEnabled(false);
In AndroidManifest:
android:windowSoftInputMode="adjustNothing"
The adapter:
public class RecyclerContactAdapter extends RecyclerView.Adapter<RecyclerContactAdapter.ViewHolder> {
private List<MobileContact> contacts;
private Context context;
public RecyclerContactAdapter() {
contacts = new ArrayList<>();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
this.context = parent.getContext();
View view = LayoutInflater.from(context)
.inflate(R.layout.item_recycler_contact, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
//set data for view
}
@Override
public int getItemCount() {
return contacts.size();
}
protected class ViewHolder extends RecyclerView.ViewHolder {
private TextView tvAlphabetHeader;
private CircleImageView civAvatar;
private TextView tvContactName;
private TextView tvStatus;
private CheckBox cbInvited;
private RelativeLayout rlAlphabetHeader;
private RelativeLayout rlContainer;
protected ViewHolder(View itemView) {
super(itemView);
tvAlphabetHeader = itemView.findViewById(R.id.item_recycler_contact_tv_alphabet_header);
civAvatar = itemView.findViewById(R.id.item_recycler_contact_civ_avatar);
tvContactName = itemView.findViewById(R.id.item_recycler_contact_tv_name);
tvStatus = itemView.findViewById(R.id.item_recycler_contact_tv_status);
cbInvited = itemView.findViewById(R.id.item_recycler_contact_cb_contact);
rlAlphabetHeader = itemView.findViewById(R.id.item_recycler_contact_rl_alphabet);
rlContainer = itemView.findViewById(R.id.item_recycler_contact_rl_contact);
}
}
public void addAll(List<MobileContact> mobileContacts) {
this.contacts.clear();
this.contacts.addAll(mobileContacts);
notifyDataSetChanged();
}
public void add(MobileContact mobileContact) {
this.contacts.add(mobileContact);
}
public List<MobileContact> getContacts() {
return this.contacts;
}
}
Use the setHasFixedsize method If the height of our RecyclerView items is fixed then we should use the setHasFixedsize method in our XML of our card item. This will fix the height of our RecyclerView item and prevent it from increasing or decreasing the size of our Card Layout.
The RecyclerView widget manages the display and handling of items in a list. It provides Layout Managers to position these items. This way, you can create customized layout managers for RecyclerView containers. We can use a RecyclerView inside another RecyclerView.
setnestedscrollingenabled set it to false.
You are using RecyclerView incorrectly. Instead of putting your RecyclerView inside NestedScrollView put your "Header" and "Search box" inside RecyclerView as different view types.
This answer is a good example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With