Skip to content
Advertisement

Android RecyclerView content not updating after notifyItemInserted

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);
        }
    });
}
9 People found this is helpful
Advertisement