2010-02-19 371 views
88

我試圖做到這一點如何更改文本在Android中的TextView

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    t=new TextView(this); 

    t=(TextView)findViewById(R.id.TextView01); 
    t.setText("Step One: blast egg"); 

    try { 
     Thread.sleep(10000); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    t.setText("Step Two: fry egg"); 

但由於某些原因,只有第二個文本顯示,當我運行它。我認爲這可能與Thread.sleep()方法阻塞有關。那麼有人可以告訴我如何實現「異步」的計時器?

謝謝。

+2

它只顯示第二行的原因是因爲'.setText()'用你告訴它設置的文本替換了整個「小部件」;包括你已經放在那裏的文字。 – georgiaboy82 2015-06-01 04:11:46

回答

43

我剛剛發佈了Android,討論谷歌集團在這個答案

如果你只是想將文本添加到視圖,以便它顯示「步驟一:爆蛋第二步:炒雞蛋」然後考慮使用t.appendText("Step Two: fry egg");代替t.setText("Step Two: fry egg");

如果你想徹底改變什麼是在TextView以便它說:「第一步:爆蛋」的啓動和然後它說「第二步:炒e GG」經過一段時間以後,你可以隨時使用

Runnable的例子sadboy給

好運

14

的新文本視圖的第一行是不必要的

​​

你可以做到這一點

TextView t = (TextView)findViewById(R.id.TextView01); 

至於那個睡在這一個後臺線程是一個例子,但我認爲有一個更好的計時器。這裏是使用定時器一個很好的例子,一個鏈接,而不是 http://android-developers.blogspot.com/2007/11/stitch-in-time.html

Thread thr = new Thread(mTask); 
    thr.start(); 
} 

Runnable mTask = new Runnable() { 
    public void run() { 
     // just sleep for 30 seconds. 
        try { 
         Thread.sleep(3000); 
         runOnUiThread(done); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
     } 
    }; 

    Runnable done = new Runnable() { 
     public void run() { 
        // t.setText("done"); 
      } 
     }; 
3

按你的意見,我使用手柄,可運行切換使用/修改的TextView的內容「計時器」。出於某種原因,運行時,應用程序總是跳過第二步(「第二步:炒雞蛋」),並只顯示最後一步(第三步)(「第三步:服務雞蛋」)。

TextView t; 
private String sText; 

private Handler mHandler = new Handler(); 

private Runnable mWaitRunnable = new Runnable() { 
    public void run() { 
     t.setText(sText); 
    } 
}; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    mMonster = BitmapFactory.decodeResource(getResources(), 
      R.drawable.monster1); 

    t=new TextView(this); 
    t=(TextView)findViewById(R.id.TextView01); 

    sText = "Step One: unpack egg"; 
    t.setText(sText); 

    sText = "Step Two: fry egg";   
    mHandler.postDelayed(mWaitRunnable, 3000); 

    sText = "Step three: serve egg"; 
    mHandler.postDelayed(mWaitRunnable, 4000);  
    ... 
} 
+1

這不能工作!只有一個處理程序 - 你想如何讓現有的mWaitRunnable跑步者「知道」sText曾經設置爲「第二步」,然後設爲「第三步」? 當它被稱爲第一次(3秒後) - sText的值只是「第三步」! 在嘗試Android編程之前,您應該熟悉基本的Java技巧! :-) – Zordid 2010-02-24 12:21:29

+0

實際上我最後做的是在runnable裏面添加了一個計數器,如果它是1,那麼文本就是這個,如果是2,文本就是這個,等等。 – user270811 2010-03-17 10:21:42

145

onCreate()方法有幾個巨大的缺陷:

1)onCreate準備你的活動 - 讓你在這裏做將作出可見給用戶,直到這個方法完成什麼!例如 - 您將永遠無法在這裏更改TextView的文本超過ONE時間,因爲只有最後的更改將被繪製,因此對用戶可見!

2)請記住,一個Android程序將 - 默認 - 運行在ONE只有線程!因此:從不在您的主線程中使用Thread.sleep()Thread.wait(),這是您的UI的責任! (閱讀"Keep your App Responsive"瞭解更多信息!)

你的初始化你的活動所做的是:

  • 沒有任何理由,你創建一個新的TextView對象t
  • 稍後在變量t中選擇佈局的TextView
  • 您設置的t文本(但要記住:它會之後onCreate()飾面和應用程序運行的主事件循環只顯示!)
  • 您等待10秒onCreate方法中 - 此絕不能完成,因爲它會停止所有UI活動,並且肯定會強制ANR(應用程序未響應,請參閱上面的鏈接!)
  • 然後您設置另一個文本 - 只要您的onCreate()方法完成和其他幾個Activity lifecycle方法en處理!

解決辦法:

  1. 設置文本僅在onCreate()一次 - 這必須是要看得見的第一個文本。

  2. 創建RunnableHandler

    private final Runnable mUpdateUITimerTask = new Runnable() { 
        public void run() { 
         // do whatever you want to change here, like: 
         t.setText("Second text to display!"); 
        } 
    }; 
    private final Handler mHandler = new Handler(); 
    
  3. 安裝此可運行的處理程序,可能在onCreate()(但是看了下面我的建議):

    // run the mUpdateUITimerTask's run() method in 10 seconds from now 
    mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000); 
    

忠告:是確定你知道Activity的生命週期!如果你在onCreate()這樣的東西,這隻會發生在你的Activity創建第一時間! Android可能會讓您的Activity長時間保持活動狀態,即使它不可見! 當用戶再次「啓動」它 - 它仍然存在 - 你不會再看到你的第一個文本!


=>總是在onResume()安裝處理器和onPause()禁用它們!否則,當你的Activity根本不可見時,你會得到「更新」! 對於您的情況,如果您想在重新激活時再次看到第一個文本,則必須將其設置爲onResume()而不是onCreate()

6

@ user264892

我發現,使用字符串變量,當我需要用任何的「」一個字符串前綴或顯式轉換爲CharSequence的。

所以不是:

String Status = "Asking Server..."; 
txtStatus.setText(Status); 

嘗試:

String Status = "Asking Server..."; 
txtStatus.setText((CharSequence) Status); 

或:

String Status = "Asking Server...";  
txtStatus.setText("" + Status); 

,或者因爲你的字符串不是動態的,甚至更好:

txtStatus.setText("AskingServer..."); 
0

:)您以錯誤的方式使用該線程。 只需執行以下操作:

private void runthread() 
{ 

splashTread = new Thread() { 
      @Override 
      public void run() { 
       try { 
        synchronized(this){ 

         //wait 5 sec 
         wait(_splashTime); 
        } 

       } catch(InterruptedException e) {} 
       finally { 
        //call the handler to set the text 
       } 
      } 
     }; 

     splashTread.start(); 
} 

就是這樣。

0

將文本設置爲sam textview會覆蓋第一個寫入的文本。 所以第二遍的時候,我們使用的setText我們只是追加新的字符串像

textview.append("Step Two: fry egg"); 
0

@Zordid @Iambda答案是偉大的,但我發現,如果我把

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000); 

在run()方法和

mHandler.postDelayed(mUpdateUITimerTask, 0); 

在onCreate方法使事情不斷更新。