简体   繁体   中英

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

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM