[英]Recycler view is not updated until you start scrolling
我在聊天。 接收和发送消息时无法显示消息。 仅当我滚动此工作表时才会出现新消息。 如果您使用scrollToPosition (0)
方法,则一切正常。 但是在这种情况下,页面会滚动,并且在收到对话者的消息时,这是不可接受的。 我已经处理这个问题大概一个星期了,我无法解决它。 我会很高兴得到任何帮助。 我附上代码:
适配器初始化:
MessagesListAdapter<IMessage> adapter;
...
adapter = new MessagesListAdapter<IMessage>(user.getUser_id(), imageLoader);
WebSocketListener(用于接收消息) :
webSocket.addListener(new WebSocketListener() {
...
@Override
public void onFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
Log.i("fg", "onFrame");
JSONObject data = new JSONObject(frame.getPayloadText());
Log.i("fg", "data: " + data.toString());
if (data.has("data")) {
switch (data.getString("type")) {
case "Text":
Log.i("fg", "type text");
MyMessage myMessage = new MyMessage(data.getString("user_id"), data.getString("data"),
data.getString("login"), data.getString("unix_time"), data.getString("user_id"), data.getString("avatar"));
Log.i("fg", "before " + Integer.toString(adapter.getItemCount()));
adapter.addToStart(myMessage, true);
adapter.notifyDataSetChanged();
break;
case "Location":
Log.i("fg", "type location");
MyLocationMessage myLocationMessage = new MyLocationMessage(data.getString("user_id"), data.getString("data"),
data.getString("login"), data.getString("unix_time"), data.getString("user_id"), data.getString("avatar"));
Log.i("fg", "before " + Integer.toString(adapter.getItemCount()));
adapter.addToStart(myLocationMessage, true);
adapter.notifyDataSetChanged();
break;
case "Photo":
Log.i("fg", "was here images");
MyImageMessage myImageMessage = new MyImageMessage(data.getString("user_id"), data.getString("data"),
data.getString("login"), data.getString("unix_time"), data.getString("user_id"), data.getString("avatar"));
Log.i("fg", "before " + Integer.toString(adapter.getItemCount()));
adapter.addToStart(myImageMessage, true);
adapter.notifyDataSetChanged();
break;
}
}
adapter.notifyDataSetChanged();
adapter.notifyItemRangeChanged(0, adapter.getItemCount());
}
适配器:
public MessagesListAdapter(String senderId, ImageLoader imageLoader) {
this(senderId, new MessageHolders(), imageLoader);
}
/**
* For default list item layout and view holder.
*
* @param senderId identifier of sender.
* @param holders custom layouts and view holders. See {@link MessageHolders} documentation for details
* @param imageLoader image loading method.
*/
public MessagesListAdapter(String senderId, MessageHolders holders,
ImageLoader imageLoader) {
this.senderId = senderId;
this.holders = holders;
this.imageLoader = imageLoader;
this.items = new ArrayList<>();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return holders.getHolder(parent, viewType, messagesListStyle);
}
@SuppressWarnings("unchecked")
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// Log.i("fg","onBindViewHolder position: " + Integer.toString(position));
Wrapper wrapper = items.get(position);
holders.bind(holder, wrapper.item, wrapper.isSelected, imageLoader,
getMessageClickListener(wrapper),
getMessageLongClickListener(wrapper),
dateHeadersFormatter);
}
public int getMessagesCount(){
int count = 0;
for(int i = 0; i < items.size(); i++){
Wrapper wrapper = items.get(i);
if (wrapper.item instanceof IMessage) {
count++;
}
}
return count;
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public int getItemViewType(int position) {
// Log.i("fg", "position: " + Integer.toString(position));
return holders.getViewType(items.get(position).item, senderId);
}
public void addToStart(MESSAGE message, boolean scroll) {
boolean isNewMessageToday = !isPreviousSameDate(0, message.getCreatedAt());
if (isNewMessageToday) {
items.add(0, new Wrapper<>(message.getCreatedAt()));
}
Wrapper<MESSAGE> element = new Wrapper<>(message);
items.add(0, element);
notifyItemRangeInserted(0, isNewMessageToday ? 2 : 1);
if (layoutManager != null && scroll) {
layoutManager.scrollToPosition(0);
}
}
ХML 与消息列表:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.uncolor.aroundme.Dialog">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<Button
android:id="@+id/buttonLoadMore"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_gravity="center|top"
android:background="@color/transparent"
android:gravity="center"
android:text="@string/previous_messages"
android:textAllCaps="false"
android:textColor="@color/colorPrevMsgs"
android:textSize="18sp" />
<com.stfalcon.chatkit.messages.MessagesList
android:id="@+id/messagesList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:paddingTop="30dp"
android:paddingBottom="15dp"
android:clipToPadding="false"
android:layout_marginBottom="0dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent">
</com.stfalcon.chatkit.messages.MessagesList>
</FrameLayout>
我使用这个库ChatKit for Android
问题可能是 onFrame 方法不在 UI 线程中运行。 这样您就可以在 UI 中应用更改。 你可以在这里尝试 Handler。
英语:
我有同样的问题,我的业务是:viewpager+fragment; 几个片段有一个recyclerview,需要滚动才能显示; 这种情况不一定存在,但出现的概率很高; 同时我排除了三种可能:
1、数据源是同一个list;
2、主线程中的notifyDataSetChanged;
3、recyclerview的地址没变;
中文:
我有同样的问题,我的业务是一个viewpager+fragment;其中几个fragment有recyclerview,显示的时候需要手动划一下才显示;
这些情况并非必现的,但有很大一部分争议出现;
同时我已经预测到了:
1、数据源是同一个list;
2、是在主线程进行的notifyDataSetChanged;
3、recyclerview的地址始终没变;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.