I'm doing the chat. I can not make a message appear when I receive and send it. New messages appear only when I scroll this sheet. If you use the scrollToPosition (0)
method, everything works. But in this case, the page will scroll and when receiving messages from the interlocutor, which is unacceptable. I've been dealing with this problem for probably a week, and I can not fix it. I will be happy with any help. I enclose the code:
Adapter init:
MessagesListAdapter<IMessage> adapter;
...
adapter = new MessagesListAdapter<IMessage>(user.getUser_id(), imageLoader);
WebSocketListener(for message recieving) :
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());
}
Adapter:
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 with message list:
<?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>
I use this library ChatKit for Android
Probably the problem is that onFrame method is running not in UI thread. This way you can apply changes in UI. You can try Handler here.
English:
I have the same problem, my business is : viewpager+fragment; several of the fragments have a recyclerview, which needs to be scrolling before being displayed; This situation is not necessarily present, but there is a high probability of it; At the same time I have ruled out three possibilities:
1, the data source is the same list;
2, notifyDataSetChanged in the main thread;
3, the address of the recyclerview has not changed;
中文:
我有同样的问题,我的业务是一个viewpager+fragment;其中几个fragment中有recyclerview,显示的时候需要手动划一下才显示;
这种情况不是必现的,但有很大的概率出现;
同时我已经排除了三个可能性:
1、数据源是同一个list;
2、是在主线程进行的notifyDataSetChanged;
3、recyclerview的地址始终没变;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.