Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recycler view is not updated until you start scrolling

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

like image 307
Влад Сапожников Avatar asked Oct 30 '22 03:10

Влад Сапожников


1 Answers

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.

like image 92
Pavel Savchkov Avatar answered Nov 15 '22 05:11

Pavel Savchkov