我正在尝试实施一些聊天活动。
邮件必须从旧版本到最新版本(底部的新邮件,我的ListView顶部的旧邮件),我的布局上使用android:transcriptMode="alwaysScroll"
和android:stackFromBottom="true"
。
当用户滚动到列表时,应该从我的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
时向上滚动,但我希望他在当前位置冻结。
有人可以帮忙吗?
答案 0 :(得分:0)
将新数据加载到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();
}
答案 1 :(得分: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());
}
}
答案 2 :(得分:0)
在更多数据时存储firstVisible位置项索引 加载(当在ListView顶部到达时)。加载数据时 然后成功将此值位置设置为第一个选定项目 使用: -
setSelection(index);
如果不能解决您的问题请告诉我?
答案 3 :(得分: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;
}