Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android RecylerView内的所有onCreateViewHolder完成时通知_Android_Android Recyclerview - Fatal编程技术网

Android RecylerView内的所有onCreateViewHolder完成时通知

Android RecylerView内的所有onCreateViewHolder完成时通知,android,android-recyclerview,Android,Android Recyclerview,RecyclerView多次调用CreateViewHolder,然后继续将数据绑定到这些视图。我的视图创建成本有点高,因此我需要推迟其他UI任务,直到我的RecyclerView创建完所有视图 我尝试添加了一个ViewTreeObserver.OnGlobalLayoutListener,但是在第一次调用onCreateViewHolder()之前就调用了这个回调 你知道我该怎么做吗?经过一些研究,我找到了一个使用Handler的解决方案。正如你所说,我正在寻找一个漂亮的代码,这对我来说有点混

RecyclerView多次调用CreateViewHolder,然后继续将数据绑定到这些视图。我的视图创建成本有点高,因此我需要推迟其他UI任务,直到我的RecyclerView创建完所有视图

我尝试添加了一个
ViewTreeObserver.OnGlobalLayoutListener
,但是在第一次调用
onCreateViewHolder()
之前就调用了这个回调


你知道我该怎么做吗?

经过一些研究,我找到了一个使用
Handler
的解决方案。正如你所说,我正在寻找一个漂亮的代码,这对我来说有点混乱。但无论如何,它都能完美地工作

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

我的计划是,如果适配器在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 
                      }
                  });
             }

    });
}
MyCustomAdapter 注 请注意,此解决方案将在Enter页面的第一次初始化结束时执行代码,在RecyclerView的情况下可能会显示该代码。 如果屏幕滚动,可能会调用
onCreateViewHolder
。 这意味着此解决方案不保证在所有可能的
onCreateViewHolder
之后执行此处理程序消息。 它只帮助您在适配器初始化的贪婪工作期间避免主线程上的过载


另外,如果您在适配器上使用动画使其平滑显示或其他方式(使用这种方式的一个很好的理由),请不要忘记将RecyclerView置于
可见的
,而不是
消失的
,否则,适配器的初始化将永远不会发生

“我的视图创建有点贵”--我会集中精力解决这个问题。
onlayoutpleted()
自定义的
RecyclerView.LayoutManager
可能会在您想要的时间点被调用,但我只能在最后一种手段下使用该方法。Tbh,我真的无法解决视图膨胀问题。我的视图中有一些Dagger 2 component.inject()调用。我不确定它们是否弄糟了。”我真的无法解决视图膨胀问题”——使用方法跟踪来确定问题所在。
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();
}