简体   繁体   English

在您开始滚动之前,不会更新 Recycler 视图

[英]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.如果您使用scrollToPosition (0)方法,则一切正常。 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) : 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());


            }

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: Х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>

I use this library ChatKit for Android我使用这个库ChatKit for Android

Probably the problem is that onFrame method is running not in UI thread.问题可能是 onFrame 方法不在 UI 线程中运行。 This way you can apply changes in UI.这样您就可以在 UI 中应用更改。 You can try Handler here.你可以在这里尝试 Handler。

English:英语:

I have the same problem, my business is : viewpager+fragment;我有同样的问题,我的业务是:viewpager+fragment; several of the fragments have a recyclerview, which needs to be scrolling before being displayed;几个片段有一个recyclerview,需要滚动才能显示; 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; 1、数据源是同一个list;

2, notifyDataSetChanged in the main thread; 2、主线程中的notifyDataSetChanged;

3, the address of the recyclerview has not changed; 3、recyclerview的地址没变;

中文:中文:

我有同样的问题,我的业务是一个viewpager+fragment;其中几个fragment中有recyclerview,显示的时候需要手动划一下才显示;我有同样的问题,我的业务是一个viewpager+fragment;其中几个fragment有recyclerview,显示的时候需要手动划一下才显示;

这种情况不是必现的,但有很大的概率出现;这些情况并非必现的,但有很大一部分争议出现;

同时我已经排除了三个可能性:同时我已经预测到了:

1、数据源是同一个list; 1、数据源是同一个list;

2、是在主线程进行的notifyDataSetChanged; 2、是在主线程进行的notifyDataSetChanged;

3、recyclerview的地址始终没变; 3、recyclerview的地址始终没变;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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