I’ve got a RecyclerView that needs to update in real-time when content is received. It successfully shows all the content at first load. When attempting to add a new item dynamically, it makes no difference. Is there anything I’m doing wrong here? Much appreciated!
MainActivity:
RecyclerView rvClips; ClipboardRVAdapter adapter; ArrayList<Clip> clips = new ArrayList<>(); private void SetupRV() { adapter = new ClipboardRVAdapter(clips); rvClips.setAdapter(adapter); adapter.setClickListener(this); rvClips.setLayoutManager(new LinearLayoutManager(getActivity())); } //this method gets called everytime a new item is received. I confirmed that it gets called. public void OnNewClipReceived(Clip clip) { clips.add(0, clip); adapter.notifyItemInserted(0); }
Adapter:
Standard adapter code. Simply shows all the items in the recyclerview.
public class ClipboardRVAdapter extends RecyclerView.Adapter<ClipboardRVAdapter.ViewHolder> { private ItemClickListener mClickListener; ArrayList<Clip> clips; public ClipboardRVAdapter(ArrayList<Clip> clips) { this.clips = clips; } public void setClickListener(ItemClickListener itemClickListener) { this.mClickListener = itemClickListener; } public interface ItemClickListener { void onItemClick(View view, int position); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { Context context = parent.getContext(); LayoutInflater inflater = LayoutInflater.from(context); // Inflate the custom layout View contactView = inflater.inflate(R.layout.item_clipboard_clip, parent, false); // Return a new holder instance ViewHolder viewHolder = new ViewHolder(contactView); return viewHolder; } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { Clip clip = clips.get(position); holder.tvClipTitle.setText(clip.content); } @Override public int getItemCount() { return clips.size(); } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView tvClipTitle; public ViewHolder(View itemView) { super(itemView); tvClipTitle = itemView.findViewById(R.id.tvClipTitle); } @Override public void onClick(View view) { if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition()); } } }
Advertisement
Answer
Since you mentioned ‘realtime’, I’m guessing this could be a thread issue. Your code seems correct. It could be that the adapter needs to be refreshed in a runOnUiThread
function. Try this:
public void OnNewClipReceived(Clip clip) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { clips.add(0, clip); adapter.notifyItemInserted(0); } }); }