滚动到顶部时ListView加载更多

3

我正在尝试实现一些聊天功能。 消息必须按照从旧到新的顺序排序(新消息在底部,旧消息在我的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);
        }
    }

这是我实现“加载更多”功能的方法:

 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个回答

0
我遇到了同样的问题。 对我有效的解决方案是在添加新项之前更改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;
}

0

在将新数据加载到适配器后,这应该可以正常工作。

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

是的,这行代码应该在更新后将我的列表视图滚动到底部。但我希望更新后仍然停留在当前位置。 - Yuriy Kolbasinskiy

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

    }

0
在更多数据加载时(当到达ListView顶部时),请存储第一个可见位置项索引。当数据成功加载后,使用以下方法将此值位置设置为第一个选定的项:
setSelection(index);

如果这不能解决你的问题,那就告诉我吧?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接