代码之家  ›  专栏  ›  技术社区  ›  Spidey

为什么我的按钮可以触发UI滚动,而活动中的TimerTask不能?

  •  0
  • Spidey  · 技术社区  · 14 年前

    长话短说:

    我有一个这样布局的聊天活动:

    <?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>
    

    <?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和一个用于发送消息的按钮。我已在活动范围中声明适配器:

    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;
    ...
    }
    

     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();
      }
        }
    

    但在我的计时器任务里,我不能。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中的错误吗?

    1 回复  |  直到 14 年前
        1
  •  0
  •   Cheryl Simon    14 年前

    您需要在UI线程上调用对数据集(notifyDataSetChanged())的更改。TimerTask在另一个线程上被调用。有许多方法可以实现这一点,请参阅 this blog post 一系列的方法。