gpt4 book ai didi

android - 当滚动太远时,如何防止 RecyclerView 为每个中间子运行 onBindViewHolder

转载 作者:太空狗 更新时间:2023-10-29 13:03:42 26 4
gpt4 key购买 nike

我有一个 RecyclerView 作为日历,每个 View 都是一天。

(占据整个屏幕的宽度和高度)

     .----------------.   .----------------.   .----------------.   .----------------.   .----------------.   .----------------.   .----------------.
| .--------------. | | .--------------. | | .--------------. | | .--------------. | | .--------------. | | .--------------. | | .--------------. |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | (1) | | | | (2) | | | | (3) | | | | (4) | | | | (5) | | | | (...) | | | | (n) | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| '--------------' | | '--------------' | | '--------------' | | '--------------' | | '--------------' | | '--------------' | | '--------------' |
'----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------'

问题:

问题是,当用户试图滚动到一个非常遥远的 future 日期时,即提前 40 天,onBindViewHolder 会为中间的所有 39 个 child 运行,这会浪费资源,因为滚动速度如此之快,甚至没有人知道滚动期间每一天都包含什么。

因此,最后一天在显示内容之前需要一些时间,因为主线程正忙于绘制所有中间的日子,除非用户手动滚动到它们,否则这些日子将永远不可见。

需要什么:

我怎样才能防止 RecyclerView 变得疯狂加载所有这些中间的日子,此时我所需要的只是用户结束的那一天.

     .----------------.   .----------------.   .----------------.   .----------------.   .----------------.   .----------------.   .----------------.
| .--------------. | | .--------------. | | .--------------. | | .--------------. | | .--------------. | | .--------------. | | .--------------. |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | (1) | | | | (2) | | | | (3) | | | | (4) | | | | (5) | | | | (...) | | | | (n) | |
| | LOAD | | | | DONT | | | | DONT | | | | DONT | | | | DONT | | | | DONT | | | | LOAD | |
| '--------------' | | '--------------' | | '--------------' | | '--------------' | | '--------------' | | '--------------' | | '--------------' |
'----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------'

(请不要告诉我使用 scrollToPosition 而不是 smoothScrollToPosition 因为移除动画不是一个选项)

谢谢

最佳答案

您可以修改您的 Adapter 类来检查平滑滚动的状态:

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(recyclerView.getLayoutManager().isSmoothScrolling()){
// make viewholder into a "blank" here
return;
}
// regular binding
}

请注意,它有点粗糙 - 滚动期间应使 ViewHolder 为空白,否则将显示无效的日期。

这是尽可能优雅(和简单)的,因为 SmoothScroller 实际上非常原始 - 它只是一直滚动直到找到目标 View ,所以没有回调来知道何时视口(viewport)具有目标位置已经在布局中。

绑定(bind)卷轴“目标”时,您需要重新验证可见持有者。

更完美的解决方案只有在您的 ViewHolder 具有不变的统一尺寸并且您向适配器提供 smoothScroll 目标时才会起作用:

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(recyclerView.getLayoutManager().isSmoothScrolling()){
// scrollTarget is current smoothScroll target position
int diff = Math.abs(position - scrollTarget);
// viewHolderHeight is taken/cached from any viewHolder that was laid out previously
if(diff * viewHolderHeight > recyclerView.getHeight()){
// make viewholder into a "blank" here
return;
}
// still smoothscrolling, but viewholder will be visible when scroll ends
}
// regular binding
}

关于android - 当滚动太远时,如何防止 RecyclerView 为每个中间子运行 onBindViewHolder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51661562/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com