Long Story Short:我的活動更新方法是通過ArrayAdapter更新和滾動ListView,但內部TimerTask的方法用於輪詢消息(顯示在ListView中)更新ListView,但不滾動它。爲什麼?爲什麼我的按鈕可以觸發UI滾動,並且我的TimerTask在活動內部不能?
長篇:
我有這個佈局的聊天活動:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff"
>
<ListView android:id="@+id/messageList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
android:layout_weight="1"
android:fadeScrollbars="true"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
>
<EditText android:id="@+id/message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<Button android:id="@+id/button_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send"
android:onClick="sendMessage"
/>
</LinearLayout>
</LinearLayout>
內部的ListView(ID爲給messageManager)由膨脹下面的XML和它替換字符串的ArrayAdapter填充。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:background="#fff"
android:paddingLeft="2dp"
android:paddingRight="2dp"
>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#00F"
android:typeface="monospace"
android:text="2010-10-12 12:12:03"
android:gravity="left"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sender"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#f84"
android:text="spidey"
android:gravity="right"
android:textStyle="bold"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/body"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:padding="1dp"
android:gravity="left"
android:layout_below="@id/date"
android:text="Mensagem muito legal 123 quatro cinco seis."
android:textColor="#000"
/>
</RelativeLayout>
問題是:在主佈局中,我有一個用於聊天消息的EditText和一個用於發送消息的Button。我宣佈在活動範圍內的適配器:
public class ChatManager extends Activity{
private EditText et;
private ListView lv;
private Timestamp lastDate = null;
private long campaignId;
private ChatAdapter ca;
private List<ChatMessage> vetMsg = new ArrayList<ChatMessage>();
private Timer chatPollingTimer;
private static final int CHAT_POLLING_PERIOD = 10000;
...
}
所以,裏面的sendMessage(視圖V),在notifyDataSetChanged()滾動的ListView acordingly,這樣我就可以自動看到最新的聊天消息:
public void sendMessage(View v) {
String msg = et.getText().toString();
if(msg.length() == 0){
return;
}
et.setText("");
String xml = ServerCom.sendAndGetChatMessages(campaignId, lastDate, msg);
Vector<ChatMessage> vetNew = Chat.parse(new InputSource(new StringReader(xml)));
//Pegando a última data
if(!vetNew.isEmpty()){
lastDate = vetNew.lastElement().getDateSent();
//Atualizando a tela
vetMsg.addAll(vetNew);
ca.notifyDataSetChanged();
}
}
但我的TimerTask,我不能。 ListView已更新,但它不會自動滾動。我究竟做錯了什麼?
private class chatPollingTask extends TimerTask {
@Override
public void run() {
String xml;
if(lastDate != null){
//Chama o Updater
xml = ServerCom.getChatMessages(campaignId, lastDate);
}else{
//Chama o init denovo
xml = ServerCom.getChatMessages(campaignId);
}
Vector<ChatMessage> vetNew = Chat.parse(new InputSource(new StringReader(xml)));
if(!(vetNew.isEmpty())){
//TODO: descobrir porque o chat não está rolando quando chegam novas mensagens
//Descobrir também como forçar o rolamento, enquanto o bug não for corrigido.
Log.d("CHAT", "New message(s) acquired!");
lastDate = vetNew.lastElement().getDateSent();
vetMsg.addAll(vetNew);
ca.notifyDataSetChanged();
}
}
}
如何強制滾動到底部?我試過使用scrollTo使用lv.getBottom() - lv.getHeight(),但沒有奏效。這是Android SDK中的錯誤嗎?
對不起,大量的代碼,但我想這種方式的問題變得非常清楚。
我已經嘗試在我的活動中創建一個方法,然後在此處發佈問題只是爲了嘗試解決此「主UI線程外的問題」問題,但它也不起作用。 – Spidey 2010-05-20 17:24:45
setSelection(vetMsgs.size() - 1)也不起作用。 – Spidey 2010-05-20 17:53:38
其實,現在我想到了它,我不知道爲什麼notifyDatasetChanged應該導致列表滾動到底部。看起來你應該在調用notifyDatasetChanged後立即調用ListView.setSelection(vetNew.size()-1)。 – 2010-05-20 17:56:25