问题
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;
}
}
回答1:
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.
来源:https://stackoverflow.com/questions/47864644/bad-performance-when-use-recyclerview-inside-nestedscrollview