RecyclerView多次调用onCreateViewHolder,然后只是将数据绑定到这些视图。我的视图创建稍微昂贵,因此我需要推迟其余的UI任务,直到我的RecyclerView完成创建所有视图。
我尝试添加ViewTreeObserver.OnGlobalLayoutListener
,但在第一次onCreateViewHolder()
调用之前,此调用会被调用。
任何想法我该怎么做?
答案 0 :(得分:1)
经过一些研究,我找到了Handler
的解决方案。当您在寻找漂亮的代码时,这对我来说有点混乱。但是仍然可以完美地工作。
Handler
是一个类,您可以使用该类来发布消息和/或Runnable,将其添加到队列中,然后在该队列完成时执行。
我的计划是,假设适配器可在UI上工作,(创建...)(创建onCreateViewHolder
和onBindViewHolder
)的创建和初始化会立即添加到主线程。
这意味着,如果您在主线程队列中发布一条消息(与适配器所使用的命令相同),那么该消息将在任何先前的请求之后执行(在您的适配器完成对所有内容的初始化之后)。
处理程序的初始化:
private Handler mHandler;
@Override
protected void onCreate(Bundle iSavedInstanceState) {
...
mHandler = new Handler(Looper.getMainLooper());
}
CustomAdapter的初始化:
private void initializeAdapter(...) {
MyCustomAdapter lMyNewAdapter = new MyCustomAdapter(...)
...
lNewAdapter.SetOnFirstViewHolderCreation(new
MyCustomAdapter.OnFirstViewHolderCreation {
@Override
public void onCreation() {
mHandler.post(new Runnable() {
@Override
public void run() {
// Finally here, the code you want to execute
// At the end of any Create and Bind VH of your
// Adapter
}
});
}
});
}
private boolean mIsViewHolderCreationStarted;
private OnFirstViewHolderCreation mOnFirstViewHolderCreation;
public CustomItemViewAdapter onCreateViewHolder(
@NonNull ViewGroup iViewGroup, int iI) {
...
if (!mIsViewHolderCreationStarted) {
mIsViewHolderCreationStarted = true;
if (mOnFirstViewHolderCreation != null) {
// It's at this point that we want to add a new request
// in the handler. When we're sure the request of the
// adapter has begun.
mOnFirstViewHolderCreation.onCreation();
}
}
}
public void setOnFirstViewHolderCreation(OnFirstViewHolderCreation iAction) {
mOnFirstViewHolderCreation = iAction;
}
public interface OnFirstViewHolderCreation {
void onCreation();
}
请注意,此解决方案将在enteer页面的首次初始化结束时执行一个代码,在RecyclerView的情况下可以显示该代码。
屏幕滚动时可能会调用onCreateViewHolder
。
这意味着此解决方案不能保证您在所有可能的onCreateViewHolder
之后执行此处理程序消息。
在适配器初始化过程中,它只会帮助您避免MainThread上的过载。
还有其他事情,以防万一您在适配器上使用动画以使其平滑显示或发生其他事情(使用此方法的良好原因之一),请不要忘记将RecyclerView放在{{1 }},而不是VISIBLE
,否则适配器的初始化永远不会发生。