初始化一个新的 RecyclerView Adapter 是异步调用吗?

Is initializing a new RecyclerView Adapter an asynchronous call?

我的问题是,新的 RecyclerView 适配器的初始化是异步调用吗?

我正在创建一个适配器:

mRecyclerAdapter = new TestAdapter(mContext, mListImages);
mRecycler.setLayoutManager(mLayoutManager);
mRecycler.setAdapter(mRecyclerAdapter);

初始化后,我可以在这些方法之后直接调用.add()而不调用.notifyDataSetChanged(),它们仍然会添加到我的适配器中并显示。

mRecyclerAdapter = new TestAdapter(mContext, mListImages);
mRecycler.setLayoutManager(mLayoutManager);
mRecycler.setAdapter(mRecyclerAdapter);

mListImages.add( . . .);
mListImages.add( . . .);
mListImages.add( . . .);

RecyclerView 适配器是否在后台线程上自动初始化?

这是我的适配器:

public class SelectBucketAdapter extends RecyclerView.Adapter<SelectBucketAdapter.ViewHolder> {

    private static final String TAG = "SelectBucketAdapter";

    private Context mContext;
    private ArrayList<String> mBucketList;

    public SelectBucketAdapter(Context mContext, ArrayList<String> mBucketList,
                               ) {
        this.mContext = mContext;
        this.mBucketList = mBucketList;

    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.vh_selectbucketmenu_layout, viewGroup, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int i) {
        ... binding views
    }

    @Override
    public int getItemCount() {
        return mBucketList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder{

        @BindView(R.id.vh_selectbucketmenu_name)
        TextView vhBucketName;


        int mPosition;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);

        }


    }
}

Are RecyclerView adapters automatically initialized on a background thread?

不,他们不是。

Is the initialization of a new RecyclerView adapter an asynchronous call?

不,不是。

window 的布局创建和附件是 异步的。

这是什么意思?

假设我们有以下代码:

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  ...

  val adapter = MyAdapter()
  recyclerView.adapter = adapter

  adapter.list.add("1")
}

在这种情况下,我们会看到屏幕上显示“1”,因为在执行 adapter.list.add("1")RecyclerView 尚未通过其 measure-layout-draw循环.

现在让我们考虑以下代码:

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  ...

  val adapter = MyAdapter()
  recyclerView.adapter = adapter

  Handler().postDelayed({ adapter.list.add("AAA") }, 2000)
}

在这种情况下,adapter.list.add("AAA") 将在大约 2 秒内执行。只要到那时 RecyclerView 已经布局,那么改变适配器数据集就不会使 RecyclerView 显示该项目,因为 RecyclerView 不知道数据集是否受到影响一个变化。

让我们考虑以下情况:

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  ...

  val adapter = MyAdapter()
  recyclerView.adapter = adapter

  recyclerView.doOnPreDraw { adapter.list.add("preDraw") }
  recyclerView.doOnLayout { adapter.list.add("layout") }
  adapter.list.add("onCreate")
}

在这种情况下,屏幕上仍然只会显示"onCreate"

总结一下:一旦 RecyclerView 通过其测量步骤(即 View#onMeasure),除非适配器明确通知 RecyclerView.[=28,否则不会反映变异适配器=]

'intiializing' 一词含糊不清。您在什么时候考虑适配器 'intiialized'?对我来说,Adapter 可以用 0 个项目初始化。因此,您无法通过查看 RecyclerView.

的内容来真正衡量 Adapter 是否已被初始化。

其次,你问的是 'intiializing is an asynchronous call'。 RecyclerView Adapter 的 'initialization' 是一大堆调用。您观察到这些调用的结果并不总是立即可见 - 这告诉您至少幕后发生的某些事情是异步的。

我想你想问的是'at what point in the lifecycle of a RecyclerView are you required to notify the Adapter of changes'。听起来答案是“一旦 RecyclerView 达到 onMeasure()(基于@azizbekian 的回答)。

如果您想在不调用 notifyDataSetChanged() 的情况下将项目添加到适配器,那么我建议在调用 RecyclerView.setAdapter() 之前添加它们。设置 Adapter 后,您对适配器的数据集所做的任何进一步更改都应跟随 notifyDataSetChanged() 调用(或者最好是更具体的 notifyX() 调用之一)。