My question is, is the initialization of a new RecyclerView
adapter an asynchronous call?
I have an adapter that I am creating:
mRecyclerAdapter = new TestAdapter(mContext, mListImages);
mRecycler.setLayoutManager(mLayoutManager);
mRecycler.setAdapter(mRecyclerAdapter);
After initializing it, I can call .add()
directly after these methods without calling .notifyDataSetChanged()
and they would still be added to my adapter, and displayed.
mRecyclerAdapter = new TestAdapter(mContext, mListImages);
mRecycler.setLayoutManager(mLayoutManager);
mRecycler.setAdapter(mRecyclerAdapter);
mListImages.add( . . .);
mListImages.add( . . .);
mListImages.add( . . .);
Are RecyclerView
adapters automatically initialized on a background thread?
Here is my adapter:
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?
No, they are not.
Is the initialization of a new
RecyclerView
adapter an asynchronous call?
No, it is not.
The layout creation and attachment to window is async.
Assume we have following code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
val adapter = MyAdapter()
recyclerView.adapter = adapter
adapter.list.add("1")
}
In this case we will see the "1" being displayed on the screen, because at the point when adapter.list.add("1")
was executed RecyclerView
hasn't yet passed through its measure-layout-draw
cycle.
Now let's consider following code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
val adapter = MyAdapter()
recyclerView.adapter = adapter
Handler().postDelayed({ adapter.list.add("AAA") }, 2000)
}
In this case adapter.list.add("AAA")
will be executed in roughly 2 seconds. As long as RecyclerView
will already be laid out by that time, then mutating the adapter dataset won't make the RecyclerView
show the item, because RecyclerView
doesn't know if dataset has suffered a change.
Let's consider following case:
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")
}
In this case still only "onCreate" will be displayed on screen.
To sum up: as soon as RecyclerView
has passed its measure step (i.e. View#onMeasure
) then mutating adapter won't be reflected unless adapter explicitly notifies RecyclerView.