ListView загрузить больше в начале прокрутки

Я пытаюсь реализовать некоторые действия в чате. Сообщения должны быть отсортированы от старых к новым (новые сообщения внизу, старые - вверху моего ListView), для этого я использую android:transcriptMode="alwaysScroll" а также android:stackFromBottom="true" на моем макете. Когда пользователь прокручивает вверх, ListView должен обновляться из старых сообщений из моей базы данных SQL. Вот некоторый код:

 public void onLoadFinished(Loader loader, Object data) {
        final Cursor cursor = (Cursor)data;

        if(cursor.getCount() > API_REQUEST_COUNT) {
            this.lsView.setStackFromBottom(false);
        }

        this.mAdapter.changeCursor(cursor);

        if(this.mAdapter.getCount() > 0) {
           this.isLoading = false;                
            }, 500);
        }
    }

И вот как я реализую функцию Load More:

 this.lsView.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {

        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            int currentItemPosition = totalItemCount - firstVisibleItem;

            // TODO without refreshing cache :-(
            if(totalItemCount == 0 && !isLoading) {
                isLoading = true;

                if(getLoaderManager().getLoader(loaderId) != null) {
                    getLoaderManager().restartLoader(loaderId, getArguments(), ConversationFragment.this);
                } else {
                    getLoaderManager().initLoader(loaderId, getArguments(), ConversationFragment.this);
                }

                // TODO pagination
                ApiManager.getInstance().getDialog(dialogId, pageNum);
            }

            if(!isLoading && totalItemCount != 0 && currentItemPosition == (API_REQUEST_COUNT * pageNum) - 1) {
                pageNum++;

                ApiManager.getInstance().getDialog(dialogId, pageNum);
            }
        }
    });

Проблема в том, когда я обновляю свой адаптер ListView прокрутите вверх, но я хочу, чтобы он завис на текущей позиции. Кто-нибудь может помочь?

4 ответа

После загрузки новых данных в Adpater это должно работать нормально

 this.lsView.setSelection(this.mAdapter.getCount() - 1);

для этого попробуйте это, это сохранит позицию прокрутки

if(listView.getAdapter()==null)
   listView.setAdapter(this.mAdapter);
else{
   this.myAdapter.updateData(myNewData); //update your adapter's data
   this.myAdapter.notifyDatasetChanged();
}

Я сталкиваюсь с той же проблемой. Решение, которое работало для меня, заключалось в добавлении новых элементов для изменения TranscriptMode:

listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_NORMAL);

После добавления:

//inserted= number of inserted items
listView.setSelection(inserted+firstVisibleItem);

и в onScrollStateChanged и onScroll я помещаю TranscriptMode обратно в оригинал:

if (inserted>0) {
listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
inserted = 0;
}

Использовать этот,

listview.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState1) {
                // TODO Auto-generated method stub
                scrollState = scrollState1;
                isScrollCompleted();

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem1,
                    int visibleItemCount1, int totalItemCount1) {
                // TODO Auto-generated method stub
                 firstVisibleItem = firstVisibleItem1;
                    visibleItemCount = visibleItemCount1;
                    totalItemCount=totalItemCount1;

            }
        });

это isScrollCompleted().

private void isScrollCompleted() {

        if(arrayList.size()>20)
        {
            Log.v("firstVisible", firstVisibleItem+"");
            Log.v("visibli", "item count"+visibleItemCount);
            Log.v("ScrollState", "scrollState"+scrollState);
            Log.v("total", totalItemCount+"");
            int lastInScreen=firstVisibleItem+visibleItemCount;
            if (lastInScreen == totalItemCount && scrollState == 0) {
                start=start+20;
                //get new twenty recornd in list and notify adapter
                cAdapter.notifyDataSetChanged();
            }
        }
        else
        {
            Log.v("arrayList", "size="+arrayList.size());
        }

    }

Сохраните индекс элемента позиции firstVisible во время дополнительной загрузки данных (при достижении в верхней части ListView). при успешной загрузке данных установите для этой позиции значения первый выбранный элемент, используя:-

setSelection(index);

Если это не решит вашу проблему, то дайте мне знать?

Другие вопросы по тегам