RecyclerView: добавленные элементы не отображаются

Добавлены элементы в recyclerView, которые не отображаются до тех пор, пока пользователь не прокрутит. Я использую веб-сокеты для связи. Когда пользователь на сервере отправляет сообщение, сервер возвращает json, который я анализирую для модели, и я добавляю его в адаптер recyclerview. Элемент добавлен в recyclerview, но он не отображается, пока я не прокручиваю recyclerview вверх или вниз. Я сделал тест, в котором я добавил статическую строку с тестовым Json, и когда я нажму на кнопку, он вызовет тот же метод, но с тестовыми данными вне веб-сокета, и он добавит элемент поверх recyclerview.

Добавленные элементы с помощью этого метода не отображаются до тех пор, пока пользователь не прокрутит:

WebSocket ws = factory.createSocket("wss://example.com/websocket");
ws.addListener(new WebSocketAdapter() {
            @Override
            public void onTextMessage(WebSocket websocket, String text) throws Exception {
                adapter.add(parseWs(text);
            }
});

private Discussion parseWs(String string) {
    discussion = new JSONObject(string).getJSONObject("data").toString();
    Gson gson = new Gson();
    return gson.fromJson(discussion, Discussion.class);
}

////////////Adapter class////////////
public void add(Discussion disc) {
    list.add(0,disc);
    notifyItemInserted(0);
}

Если я добавляю элемент при нажатии на кнопку, элементы отображаются нормально без прокрутки:

fab.setOnClickListener(v -> 
    adapter.add(parseWs(test));
    mRecyclerView.scrollToPosition(0);
);

Я использую java-библиотеку nv-weboskcet-client.


person mayyo    schedule 16.06.2016    source источник


Ответы (1)


Не уверен, что вы точно хотите, но попробуйте использовать

notifyDataSetChanged();

Пусть это решит вашу проблему.

Если вызов асинхронный, вы должны использовать класс Handler для обновления представления.

Android и JavaRx:

https://mttkay.github.io/blog/2013/08/25/functional-reactive-programming-on-android-with-rxjava/

Но просто попробуйте это с классом Handler.

Handler handler = new Handler();
ws.addListener(new WebSocketAdapter() {
    @Override
    public void onTextMessage(WebSocket websocket, String text) throws Exception {
        handler.post(new Runnable(){
            adapter.add(parseWs(text);
        });
    }
});

Что-то вроде этого должно работать :)

Возможно, вам придется объявить Handler handler как поле в вашей деятельности.

person Monarchis    schedule 16.06.2016
comment
этот метод прерывает анимацию, и я уведомляю адаптер о добавлении элемента, вы можете увидеть это в коде - person mayyo; 16.06.2016
comment
Вы пробовали это с классом Handler, чтобы обновить свой вид? Потому что кажется, что WebSocket обрабатывает сообщения в другом потоке. - person Monarchis; 16.06.2016
comment
Похоже, вы правы, веб-сокет создает отдельный поток от пользовательского интерфейса, поэтому я попытаюсь использовать обработчик для обновления пользовательского интерфейса. Есть ли возможность использовать метод синхронного подключения с RxJava? - person mayyo; 16.06.2016