如何在不刷新整个列表的情况下使用实时数据更新特定的 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。
我正在学习 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。