需求:聊天消息列表頁面,收到新消息后自動滾動到 ListView 的底部
很簡單,在接收到新消息的回調方法中調用 ListView.setSelection(int)
就可以了:
lv.setSelection(lv.getAdapter().getCount() - 1);
加上了代碼,運行后發個消息試試,結果,完全沒效果...
于是想到了要加個post()
,將代碼改成了:
lv.post(new Runnable() {
@Override
public void run() {
lv.setSelection(lv.getAdapter().getCount() - 1);
}
});
再次運行,還是沒效果...
之后又試了下面各種方法:
lv.setSelection();
lv.setSelectionFromTop();
lv.smoothScrollToPosition();
lv.smoothScrollToPositionFromTop();
沒辦法,只能求助 Google,于是搜索:"listview setselection not work",發現遇到這個問題的同學還真不少,接著試了下面幾個方法的各種排列組合:
lv.clearFocus();
lv.requestFocusFromTouch();
lv.setItemChecked();
lv.smoothScrollBy();
lv.scrollTo();
但是...依然不行...抓狂中
最后 Debug,一步一步的跟蹤方法的調用,終于找到了原因:
新消息的回調事件是在子線程中執行的,接收到消息后在子線程中把新消息添加到了 Adapter 中并且執行 Adapter.notifyDataSetChanged()
,最終代碼:
lv.post(new Runnable() {
@Override
public void run() {
mAdapter.addData(messages);
lv.smoothScrollToPosition(lv.getAdapter().getCount() - 1);
}
});
參考:
stackoverflow: ListView.setSelection is not working
stackoverflow: Android ListView setSelection() does not seem to work