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:
JavaScript
x
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.
JavaScript
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:
JavaScript
public void OnNewClipReceived(Clip clip) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
clips.add(0, clip);
adapter.notifyItemInserted(0);
}
});
}