Android recyclerView 滚动不流畅,有很多视图要在旧设备上绑定

Android recyclerView is not scrolling smoothly with a lot of views to bind on older device

我有一个 recyclerView 和一个 adapter 正在膨胀自定义布局(Folding cell 库)。充气后,在 onCreateViewHolder 中,我正在初始化很多视图(主要是 textViews),如下所示:

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

FoldingCell v = (FoldingCell) LayoutInflater.from(parent.getContext())
        .inflate(R.layout.custom_layout, parent, false);


    ConstraintLayout continueBTN = v.findViewById(R.id.continueBTN);
    TextView num = v.findViewById(R.id.num);
    TextView name = v.findViewById(R.id.name);
    TextView surname = v.findViewById(R.id.surname);
    TextView add = v.findViewById(R.id.add);
    TextView add2 = v.findViewById(R.id.add2);
    TextView currency = v.findViewById(R.id.currency);
    TextView currency2 = v.findViewById(R.id.currency2);
    ConstraintLayout del = v.findViewById(R.id.DeleteICN);
    ConstraintLayout rnme = v.findViewById(R.id.renameBtn);
    TextView fText = v.findViewById(R.id.fText);
    TextView tText = v.findViewById(R.id.tText);
    TextView continue = v.findViewById(R.id.cnt);
    TextView total= v.findViewById(R.id.total);
    FoldingCell cell = v.findViewById(R.id.fcell);


    ViewHolder vh = new ViewHolder(cell, continueBTN,num, name, surname, add, add2, price, currency, currency2, del, rnme, fText, tText, continue,total );

    vh.bind(onCardClickListener);

    return vh;
}

以上观点都可能通过 BaaS 进行更改,这就是为什么我将它们插入 viewHolder 如果有意义的话。 cell 视图是包含上面其他视图的容器,我还需要对其进行初始化,因为如果回收的 Folding cell 恰好展开,那么当再次在屏幕上滚动时,我想让它保持展开状态,因为默认情况下,folding cell 被折叠。

因此在 onBindViewHolder 这就是我正在做的事情:

@Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    // if this view holder position was left unfolded
        if (unfoldedIndexes.contains(position)) {

            // show it as unfolded again
            holder.cell.unfold(true);

            // only bind the views created in onCreateViewHolder that correspond to the unfolded state of the cell
            bindUnfoldedState(holder, holder.getLayoutPosition());
        }else{
            holder.cell.fold(true);

        // only bind the  views created in onCreateViewHolder that correspond to the folded state of the cell 
            bindFoldedState(holder, holder.getLayoutPosition());
        }
    }

public void bindFoldedState(ViewHolder holder, int position){

    CustomLayout customLayout = myArrayList.get(position);
    String formattedPrice = context.getString(R.string.currency, customLayout.getP());

    holder.currency.setText(formattedPrice);

    holder.add.setText(customLayout.getConName());

    holder.num.setText(customLayout.getNum());

    holder.total.setText(""+customLayout.getTotal());

}

public void bindUnfoldedState(ViewHolder holder, int position){

           holder.tText.setTextColor(Color.parseColor("#6F90CF"));
            holder.fText.setText(location.getToTime());
     //  …
     // and the rest of the views exactly the same way

        if (location.getRequestBtnClickListener() != null) {

            // seting some onClickListeners on views
        }
}

这一切都很好。 .. 在模拟器上。但是,在真实设备(旧的,二手的,2015 api 23 Galaxy A5)上,当新视图进入屏幕时,应用程序会丢掉很多帧,从而导致滚动不稳定。设备上的开发工具显示绑定数据花费的时间超过 16 毫秒。

为了证实这一点,我注释了onBindViewHolder()中的所有代码,滚动非常流畅。

那么问题来了,如何快速绑定以上所有数据呢? recyclerView 中的每个元素都包含上述所有可能通过 BaaS 更改的子视图。

我创建的布局中也没有最平坦的层次结构。我只使用 Constraint Layout 这可能会有所帮助,但我不认为问题是由层次结构引起的,因为通过我上面提到的 onBindViewHolder() 测试。

将您的 onCreateViewHolder 方法更新为:

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 FoldingCell v=LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_layout, parent, false);
        return new ViewHolder(v);
}

像这样创建视图持有者:

public static class ViewHolder extends RecyclerView.ViewHolder {  
        public ConstraintLayout continueBTN 
        public TextView textView,name,surname,add;  

        public ViewHolder(View itemView) {  
            super(itemView);  
            continueBTN = (ConstraintLayout) itemView.findViewById(R.id.continueBTN);  
            num= (TextView) itemView.findViewById(R.id.num);
            name= (TextView) itemView.findViewById(R.id.name);
            surname= (TextView) itemView.findViewById(R.id.surname);
            add= (TextView) itemView.findViewById(R.id.add);
           /...../          
             }  
    }  

如果您的回收站视图在嵌套滚动视图中,请使用此行:

  recyclerView.setNestedScrollingEnabled(false);

按原样使用您的 bindViewHolder。 希望这对您有所帮助