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。
希望这对您有所帮助
我有一个 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。 希望这对您有所帮助