当RecylerView中的所有onCreateViewHolder完成时通知

时间:2018-02-01 12:39:21

标签: android android-recyclerview

RecyclerView多次调用onCreateViewHolder,然后只是将数据绑定到这些视图。我的视图创建稍微昂贵,因此我需要推迟其余的UI任务,直到我的RecyclerView完成创建所有视图。

我尝试添加ViewTreeObserver.OnGlobalLayoutListener,但在第一次onCreateViewHolder()调用之前,此调用会被调用。

任何想法我该怎么做?

1 个答案:

答案 0 :(得分:1)

经过一些研究,我找到了Handler的解决方案。当您在寻找漂亮的代码时,这对我来说有点混乱。但是仍然可以完美地工作。

Handler是一个类,您可以使用该类来发布消息和/或Runnable,将其添加到队列中,然后在该队列完成时执行。

我的计划是,假设适配器可在UI上工作,(创建...)(创建onCreateViewHolderonBindViewHolder)的创建和初始化会立即添加到主线程。

这意味着,如果您在主线程队列中发布一条消息(与适配器所使用的命令相同),那么该消息将在任何先前的请求之后执行(在您的适配器完成对所有内容的初始化之后)。

示例:

主要活动

处理程序的初始化:

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

    });
}

MyCustomAdapter

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,否则适配器的初始化永远不会发生。