繁体   English   中英

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

[英]Recycler view is not updated until you start scrolling

我在聊天。 接收和发送消息时无法显示消息。 仅当我滚动此工作表时才会出现新消息。 如果您使用scrollToPosition (0)方法,则一切正常。 但是在这种情况下,页面会滚动,并且在收到对话者的消息,这是不可接受的。 我已经处理这个问题大概一个星期了,我无法解决它。 我会很高兴得到任何帮助。 我附上代码:

适配器初始化:

MessagesListAdapter<IMessage> adapter;
...
adapter = new MessagesListAdapter<IMessage>(user.getUser_id(), imageLoader);

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());


            }

适配器:

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 与消息列表:

<?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>

我使用这个库ChatKit for Android

问题可能是 onFrame 方法不在 UI 线程中运行。 这样您就可以在 UI 中应用更改。 你可以在这里尝试 Handler。

英语:

我有同样的问题,我的业务是:viewpager+fragment; 几个片段有一个recyclerview,需要滚动才能显示; 这种情况不一定存在,但出现的概率很高; 同时我排除了三种可能:

1、数据源是同一个list;

2、主线程中的notifyDataSetChanged;

3、recyclerview的地址没变;

中文:

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

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

同时我已经预测到了:

1、数据源是同一个list;

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

3、recyclerview的地址始终没变;

暂无
暂无

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

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