I'm trying to implement some chat activity.
Messages must be ordreded from older to newest (new messages on a bottom, older on a top of my ListView), for that i'm using android:transcriptMode="alwaysScroll" and android:stackFromBottom="true" on my layout.
When user scroll to up ListView should be updated from older messages from my SQL database. Here is some code:
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);
}
}
And this is how i implement Load More function:
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);
}
}
});
The problem is, when i update my adapter ListView scroll to up, but i want that he freezes on a current position.
Can anybody help?
4 Answers 4
after loading the New Data into Adpater this should work fine
this.lsView.setSelection(this.mAdapter.getCount() - 1);
for that Try this,this will retain the scroll position
if(listView.getAdapter()==null)
listView.setAdapter(this.mAdapter);
else{
this.myAdapter.updateData(myNewData); //update your adapter's data
this.myAdapter.notifyDatasetChanged();
}
1 Comment
use this,
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;
}
});
this is 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());
}
}
Comments
Store the firstVisible position item index at the time of more data loading (when reached at top of ListView). when data loaded successfully then set this value position to first Selected item using:-
setSelection(index);
If it not solve your problem Then let me know?
Comments
I run into the same problem. The solution that worked for me was before adding the new items to change the TranscriptMode:
listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_NORMAL);
After adding:
//inserted= number of inserted items
listView.setSelection(inserted+firstVisibleItem);
and in the onScrollStateChanged and onScroll I put the TranscriptMode back to the original:
if (inserted>0) {
listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
inserted = 0;
}
Comments
Explore related questions
See similar questions with these tags.