I've been doing a lot of fiddling with an issue I've been having. What happens is each time an item gets added to my listview (adapter) I expect it to auto-scroll if I'm at the last item (which it will do to an extent); HOWEVER, if 3 or more items get added at once, it will not auto-scroll.
Here is the XML of that listview:
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:transcriptMode="normal"/>
I tried a workaround using a snippet I found here.
My code is as follows:
public void addChat(final String text, final String username) {
this.runOnUiThread(new Runnable() {
public void run() {
globals.chatAdapter.add(DateFormat.format("hh:mmaa", Calendar.getInstance()).toString(), username, text);
globals.chatAdapter.notifyDataSetChanged();
int lastP = getListView().getLastVisiblePosition();
int count = globals.chatAdapter.getCount() - 1;
if (lastP == globals.chatAdapter.oldP || lastP == -1) {
getListView().setSelection(count);
}
globals.chatAdapter.oldP = count;
}
});
}
The problem with this is when a bunch of items come in at once, getListView().getLastVisiblePosition() will not update right away causing a setSelection() to never get called, and thus no auto-scroll.
Any suggestions?
As a workaround, I modified the scroll listener...a little crude, but it gets the job done.
OLD CODE - NEW CODE FOUND AFTER EDIT BELOW
this.getListView().setOnScrollListener(new OnScrollListener() {
public void onScroll(AbsListView view, int first, int visible, int total) {
if (visible == 0 || visible < total && (first + visible == total) || (getListView().getTranscriptMode() == 2) && (first + visible == total)) {
if (getListView().getTranscriptMode() != 2)
getListView().setTranscriptMode(2);
} else {
if (getListView().getTranscriptMode() != 0)
getListView().setTranscriptMode(0);
}
}
public void onScrollStateChanged(AbsListView view, int scrollState) {}
});
EDIT 6/6/11:
I went ahead and modified it again as I found a UI bug in my own implementation (The initial snap to the bottom wouldn't hold after I removed my alwaysScroll xml setting). I'll leave the old code above, but here's what I'm using now:
getListView().setOnScrollListener(new OnScrollListener() {
public void onScroll(AbsListView view, int first, int visible, int total) {
if (visible == 0 || visible == total || (first + visible == total) {
if (getListView().getTranscriptMode() != AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL)
getListView().setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
} else {
if (getListView().getTranscriptMode() != AbsListView.TRANSCRIPT_MODE_DISABLED)
getListView().setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED);
}
}
public void onScrollStateChanged(AbsListView view, int scrollState) {}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With