Android 在NestedScrollView中使用RecyclerView时性能不佳

Android 在NestedScrollView中使用RecyclerView时性能不佳,android,performance,android-recyclerview,android-nestedscrollview,Android,Performance,Android Recyclerview,Android Nestedscrollview,我正在开发一个搜索联系人功能,在该屏幕中,嵌套的ScrolView(fillViewport=true)中有一个RecyclerView。 屏幕设计:(此设计已被客户接受,我无法更改它) 将当前设备的所有联系人加载到ArrayList后,将从此数组中筛选搜索结果。 有几种情况使应用程序非常滞后: 1.当用户键入一个没有结果的输入,然后用户清除搜索时,我必须再次显示所有结果。NestedScrollView必须呈现所有RecyclerView项目的UI(例如:300个项目)。 2.当结果的数量有

我正在开发一个搜索联系人功能,在该屏幕中,嵌套的ScrolView(fillViewport=true)中有一个RecyclerView。 屏幕设计:(此设计已被客户接受,我无法更改它

将当前设备的所有联系人加载到ArrayList后,将从此数组中筛选搜索结果。
有几种情况使应用程序非常滞后:
1.当用户键入一个没有结果的输入,然后用户清除搜索时,我必须再次显示所有结果。NestedScrollView必须呈现所有RecyclerView项目的UI(例如:300个项目)。
2.当结果的数量有很多变化时(例如,从1到300项)。嵌套滚动视图必须为大量的回收视图

我知道这个设计打破了RecyclerView的回收技术,但我不能改变它
我尝试的是:

recyclerView.setNestedScrollingEnabled(false);
在AndroidManifest中:

android:windowSoftInputMode="adjustNothing"
适配器:

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;
    }

}
公共类RecyclerContactAdapter扩展了RecyclerView.Adapter{ 私人名单联系人; 私人语境; 公共回收商ContactAdapter(){ 联系人=新的ArrayList(); } @凌驾 public ViewHolder onCreateViewHolder(视图组父级,int-viewType){ this.context=parent.getContext(); 视图=LayoutFlater.from(上下文) .充气(R.layout.item\u recycler\u contact,parent,false); 返回新的ViewHolder(视图); } @凌驾 公共无效onBindViewHolder(ViewHolder,int位置){ //为视图设置数据 } @凌驾 public int getItemCount(){ 返回contacts.size(); } 受保护的类ViewHolder扩展了RecyclerView.ViewHolder{ 私有文本视图TVALPHEADER; 私人CircleImageView civAvatar; 私有文本视图tvContactName; 私有文本视图状态; 邀请私人参选; 私人相对人; 私有相对论容器; 受保护的ViewHolder(视图项视图){ 超级(项目视图); tvAlphabetHeader=itemView.findViewById(R.id.item\u recycler\u contact\u tv\u alphabet\u header); civAvatar=itemView.findviewbyd(R.id.item\u recycler\u contact\u civ\u avatar); tvContactName=itemView.findViewById(R.id.item\u recycler\u contact\u tv\u name); tvStatus=itemView.findViewById(R.id.item\u recycler\u contact\u tv\u状态); cbinvested=itemView.findviewbyd(R.id.item\u recycler\u contact\u cb\u contact); rlAlphabetHeader=itemView.findViewById(R.id.item\u recycler\u contact\u rl\u字母表); rlContainer=itemView.findviewbyd(R.id.item\u recycler\u contact\u rl\u contact); } } public void addAll(列出MobileContact){ this.contacts.clear(); this.contacts.addAll(mobileContacts); notifyDataSetChanged(); } 公共作废添加(MobileContact MobileContact){ this.contacts.add(mobileContact); } 公共列表getContacts(){ 把这个还给我。联系方式; } }
您不正确地使用了RecyclerView。不要将RecyclerView放在NestedScrollView中,而是将“标题”和“搜索框”作为不同的视图类型放在RecyclerView中


这是一个很好的例子。

发布你的recyler Adapter你能再解释一下你的ui设计吗?其中哪一部分是可滚动的?Ie您可以滚动nestedscrollview,也可以在nestedscrollview内循环查看或什么?@Okas除了工具栏,用户可以滚动整个页面screen@ErginErsoy好的,我要发布它,如果我不使用NestedScrollView,这个功能可以顺利工作,因为使用了回收技术。为什么需要ScrollView,当RecyclerView已经可以自己滚动时?!这种方法听起来很合适,但会有4种不同的视图类型:标题(TextView)、按钮、搜索框、普通项目,处理每个项目的所有事件时都很复杂,只是一开始看起来很复杂。实际上,这是标准做法。同时看看你的用户界面,你似乎可以把你的标题,按钮和搜索框放在一个布局中,所以只有两种视图类型。哦,我明白了,我希望我能给你展示准确的屏幕设计。我将尝试您的解决方案。如果列表上有一个片段,我无法将所有逻辑从片段移动到适配器中的标头,该怎么办?而且适配器内部不能使用碎片。@David,您可能需要重新设计。