Issue
I have some trouble to understand why my recyclerView get update while I add the data only after setAdapter() and never call notifyDataSetChanged() !
In the same type: -> I add 3 String to my list -> Notify the adapter only for the first added (notifyItemInserted)
Result: 3 String displayed.
If anyone can help me understand I will be very grateful to him :)
https://www.noelshack.com/2018-04-5-1516969446-recycler.png
my code:
public class MainActivity extends AppCompatActivity {
List<String> mList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Call before set adapter so it's normal if show when the adapter is set
mList.add("Before set the adapter");
RecyclerView recyclerView = findViewById(R.id.rcv);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
final Adapter mAdapter = new Adapter(mList);
recyclerView.setAdapter(mAdapter);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mList.add("Button add " +0);
mAdapter.notifyItemInserted(mList.size()-1);
//Again it's showing but never notify
mList.add("Button add " +1);
mList.add("Button add " +2);
}
});
//Called after setAdapter and NEVER notify the adapter but it's still show the data
addMoreData();
}
private void addMoreData() {
for (int i = 0; i < 10; i++) {
mList.add("addMoreData: " + i);
}
}
class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
class ViewHolder extends RecyclerView.ViewHolder {
TextView nameTextView;
ViewHolder(View itemView) {
super(itemView);
nameTextView = (TextView) itemView.findViewById(R.id.textview);
}
}
@Override
public Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.raw, parent, false);
return new Adapter.ViewHolder(view);
}
private List<String> mList;
Adapter(List<String> list) {
mList = list;
}
@Override
public void onBindViewHolder(Adapter.ViewHolder holder, int position) {
holder.nameTextView.setText(mList.get(position));
}
@Override
public int getItemCount() {
return mList.size();
}
}
}
Solution
I think, because of notifyDataSetChanged
's working principle, this is the result.
A Google engineer said ;
When you call notifyDataSetChanged, RecyclerView invalidates the data but does not update the UI until the next animation frame. This is how android view system works. When a widget is invalidated (e.g. changing its data) it requests a layout which means it will be re-measured and re-laid out in the next view traversal. This is done so that we can batch all changes until the next time screen will be updated.
That means; nofiyDataSetChanged
waits the UI Thread. So, doesn't matter the below lines of the notifyItemInserted
from your code.
mList.add("Button add " +0);
mAdapter.notifyItemInserted(mList.size()-1);
//Again it's showing but never notify
mList.add("Button add " +1);
mList.add("Button add " +2);
Answered By - ziLk
Answer Checked By - Cary Denson (JavaFixing Admin)