Страницы

Поиск по вопросам

пятница, 24 января 2020 г.

Обновить listview методом notifyDataSetChanged сохранив текущее положение

#java #android #listview #recyclerview


Есть listview в котором данные обновляются сверху, как сообщения вконтакте, проблема
в том, что когда я получаю следующую часть items listview для обновления. 




Пробовал сохранять текущее положение firstVisibleItem в методе onScrollStateChanged(),
но это неправильно работает:

public void onScrollStateChanged(AbsListView view, int scrollState)
{
    if (enableLoading)
    {
        if (currentVisibleItemCount > 0 && scrollState ==  SCROLL_STATE_TOUCH_SCROLL)
        {
            int i = 0;
            if (currentFirstVisibleItem == 7)
            {
                updateMessagesList();//get 20 elements
            }
            _listView.setSelection(i+20);
        }
    }
}

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount)
{
    currentFirstVisibleItem = firstVisibleItem;
    currentVisibleItemCount = visibleItemCount;
    currentTotalItemCount = totalItemCount;
}


Догрузка должна быть какбы "незаметной" и не влиять на текущее положение. 

Итак, я начал скролить, сработало условие firstVisibleItem == 7
Если я буду сетать значение в listview.setSelection(firstVisibleItem), а я сейчас
продолжаю например скролить listview, тогда и метод listView.setSelection(i+20); будет
работать, если только я 7 елемент "дергну" и остановлюсь на нем же. А на самом деле
как будет - меня попросту вернет назад(в моему случае на 27 елемент в списке), потому
что я продолжаю скролить, а currentFirstVisibleItem уже не равен  - 7, а тот на котором
я остановлюсь, а ведь я могу и не остановливаться, а просто скролить, что-то например
искать; плюс еще возможна задержка 1-2 секунды, потому данные приходят с API. 

Данные обновляю методом  adapter.notifyDataSetChanged();

Как мне добавлять значения до listview как бы на заднем фоне, и чтобы при добавлении
не терялся currentPosition?

Решение

public void onScrolled(RecyclerView recyclerView, int dx, int dy) 
{    
    firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
    if(firstVisibleItem == 0){
    if (loading == true) 
    {
        loading = false;
        loadMoreItems();
    }
}


Плюс перестроил активити с listview на recyclerview. Даже скорость адпатера увеличилась.
То есть заметно при работе с большим количеством.
    


Ответы

Ответ 1



Попробуйте переделать всё на современный RecyclerView вместо устаревшего ListView. В первом есть методы типа notifyItemRangeInserted, которые уведомят адаптер о наличии новых элементов в некотором диапазоне и не вызовут перерисовки всего списка

Комментариев нет:

Отправить комментарий