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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With