如何在不刷新整个列表的情况下使用实时数据更新特定的 Recyclerview 行

How to update a specific Recyclerview Row using live data without refreshing entire list

我正在学习 android,这个问题可能有答案,但找不到解决我问题的方法。好的,我正在使用 websocket 创建一个聊天应用程序并且工作正常但是我需要解决一个场景,即当用户正在与选定的用户聊天时我需要应用程序能够接收来自其他朋友的短信以便标记为未读并显示上次收到的消息(就像电报和 whatsapp 所做的那样)到目前为止,我已经实现了 LiveData 来完成它工作正常,因为我能够在我的控制台中看到日志。我的问题是 Observe 方法如何更新我的用户列表中的特定项目以创建新消息的通知计数。这是我的实时数据代码。另一个问题是如何在房间数据库中存储大文本。我想知道是否有特定的注释来指定列大小。

 public class ChatFragment extends Fragment
 
 {
   private RecyclerView recyclerView;
    private ChatAdapter adapter;
    private NotificationRepository notificationRepository;
    private NotificationListModel notificationListModel;

 
 public ChatFragment() {
        // Required empty public constructor
    }

    Map<Long,MyFriendsModel> tutor_map;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view= inflater.inflate(R.layout.chat_layout, container, false);
        recyclerView=view.findViewById(R.id.my_recycler);


        recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
                DividerItemDecoration.VERTICAL));

        adapter=new ChatAdapter(getActivity(),getUsers());
        adapter.setTutorOnclickListener(this);
        recyclerView.setAdapter(adapter);
        set_up_live_data();


        return view;
    }
 }
 
 private void set_up_live_data()
 
 {
 
 /***
 I do not know how to update my list of users to create total tallies of unread message and last message on new data from observer
 */
  notificationRepository=new NotificationRepository(mActivity);
        notificationListModel=ViewModelProviders.of(this).get(NotificationListModel.class);
        notificationListModel.getLiveNotification().observe(getViewLifecycleOwner(), new Observer<List<NotificationEntity>>() {
            @Override
            public void onChanged(@Nullable List<NotificationEntity> itemModels) {//this one is invoked from Websocket onMessageMethod and store them in sqlite

                 Log.e(TAG, "onChanged: ");// am able to see this on the console
                List<MyFriendsModel> msg=new ArrayList<>();
     
                for(NotificationEntity m:itemModels)
                {
                  
                        MyFriendsModel ms=new MyFriendsModel();
                        ms.setLast_message(m.getLast_message());//need to update particular row with this and
                       
                        ms.setTotal_unread(m.getTotal_unread());//need to update particular row with this
                        msg.add(ms);
                
                    
                }
    }
        });
 
 }
 
 private List<MyFriendsModel> getUsers() {
     
        List<MyFriendsModel> messages;//retrofit calls to fetch list of users
       
       
        return messages;
    }
    
    
    public class ChatAdapter extends RecyclerView.Adapter{
      private Context mContext;
     private List<MyFriendsModel> mMessageList;

    public ChatAdapter(Context context, List<MyFriendsModel> messageList) {
        mContext = context;
        mMessageList = messageList;
    }
  @Override
    public int getItemCount() {
        return mMessageList.size();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View  view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.chat_item_layout, parent, false);;



        return new MyHodlerHolder(view);
    }

   
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        MyFriendsModel message = mMessageList.get(position);
        ((MyHodlerHolder) holder).bind(message);

    }
    private class MyHodlerHolder extends RecyclerView.ViewHolder {
        TextView tutorName,txt_unread_chats,txt_last_sent_message;
        RelativeLayout relativeLayout;

        MyHodlerHolder(View itemView) {
            super(itemView);

            tutorName = itemView.findViewById(R.id.text_tutor_name);
            txt_unread_chats=itemView.findViewById(R.id.txt_unread_chats);
            relativeLayout=itemView.findViewById(R.id.relativeLayout);
            txt_last_sent_message=itemView.findViewById(R.id.txt_last_sent_message);

        }


        public void bind(final MyFriendsModel message)
        {
            tutorName.setText(message.getUser_name());
            txt_unread_chats.setText();//to be updated on by live data. this is where I am stuck.
            //I need to update a specific Item not refreshing the entire list
            
           
        }
    }
}

这是我需要存储大文本的实体

@Entity(tableName = "tbl_chats")
public class ChatsEntity
{

    @PrimaryKey(autoGenerate = true)
    long id;
    private String message;//need to make this column to store large text
    private String chat_date;
}

对于这种情况,我建议使用 DiffUtil。

创建一个名为 MyDiffUtil 的 class。

public class MyDiffUtil extends DiffUtil.Callback {
    private List<MyFriendsModel> newList;
    private List<MyFriendsModel> oldList;

    @Override
    public int getOldListSize() {
        return oldList.size();
    }

    @Override
    public int getNewListSize() {
        return newList.size();
    }

    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        return newList.get(newItemPosition).id == oldList.get(oldItemPosition).id;
    }

    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
        if (!oldList.get(oldItemPosition).message().equals(newList.get(newItemPosition).message()))
            return false;
        else if (!oldList.get(oldItemPosition).getUser_name().equals(newList.get(newItemPosition).getUser_name()))
            return false;
        else
            return true;
    }
}

更新您的适配器 class 为。

public void populate (List<MyFriendsModel> newMessages) {
    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new MyDiffUtil (mMessageList, newMessages));
    diffResult.dispatchUpdatesTo(this);
}

代替适配器=new ChatAdapter(getActivity(),getUsers()); 进行必要的更改并致电

adapter.populate(getUsers());

要了解更多信息,请查看 documentation