我的解决方法就是,将setSelection放到handler的post方法中,这样就解决了这个问题。
new Handler().post(new Runnable() {
@Override
public void run() {
listView.setSelection(position);
}
});
我查看了一下安卓源码。handler.post源码:
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* @param r The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
再看sendMessageDelayed源码:
/**
* Enqueue a message into the message queue after all pending messages
* before (current time + delayMillis). You will receive it in
* {@link #handleMessage}, in the thread attached to this handler.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the message will be processed -- if
* the looper is quit before the delivery time of the message
* occurs then the message will be dropped.
*/
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
同样也是很简单,但是注意!这个方法的注释这样写道:
Enqueue a message into the message queue after all pending messages 。
将一个消息加入排队在所有等待消息的最后。
看到这便恍然大悟,可能正是这个方法的原因,保证了setSelection在最后执行,而不与其他主线程的操作产生冲突。
同时想到:
关于View的测量,我们不能直接通过view.getMeasuredWidth(),view.getMeasuredHeight()方法得到高度,但是我们可以在view.post()的方法中调用view.getMeasuredWidth(),view.getMeasuredHeight()获得,其原因应该也就是,view.post()同样也调用了sendMessageDelayed()方法,它使得调用getMeasuredWidth()方法时,在消息队列的最后,此时view已经绘制完成,因此可以得到宽高度。
结论:
setSelection方法要在主线程的handler.post中进行。如果还是不行,可以试试
new Handler().post(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
listView.setSelection(position);
}
});