2014-09-25 42 views
0

我已經設置了一個名爲ButtonRoll的onClick方法的按鈕,該方法從1-100隨機生成一個數字,然後在文本視圖中顯示按鈕下方的輸出。這工作正常,但我想要移動到能夠循環20個數字生成。我已經嘗試了以下,但它只會顯示正在生成的最後一個數字。我猜這是因爲用戶界面沒有被更新,直到最後一個數字被生成。更新Android UI以顯示正在生成的隨機數字?

public void ButtonRoll(View view) { 

     int n; 
     Random rand = new Random(); 
     TextView textRoll = (TextView) findViewById(R.id.textview_roll); 
     for (int i=0; i<20; i++){ 
      try { 
       Thread.sleep(200); 
       n = rand.nextInt(100) + 1; 
       String roll = String.valueOf(n); 
       textRoll.setText("Random number is " + roll); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
     } 
    } 

我需要使用Handler嗎?還是有更簡單的解決方案? 謝謝你的時間。

回答

0

試試這個。

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:gravity="center"> 

    <Button android:id="@+id/button_roll" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="5dp" 
     android:text="Roll"/> 

    <TextView android:id="@+id/textview_roll" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@id/button_roll" /> 

</RelativeLayout> 

MainActivity.java

public class MainActivity extends Activity implements OnClickListener 
{ 
    private class Roller implements Runnable 
    { 
     private int numTimes; 
     private long delayMillis; 

     public Roller(int numTimes, long delayMillis) 
     { 
      this.numTimes = numTimes; 
      this.delayMillis = delayMillis; 
     } 

     @Override 
     public void run() 
     { 
      if (textRoll != null) 
      { 
       int n = rand.nextInt(100) + 1; 
       String roll = String.valueOf(n); 
       textRoll.setText("Random number is " + roll); 

       numTimes--; 

       if (numTimes > 0) 
       { 
        textRoll.postDelayed(this, delayMillis); 
       } 
      } 
     } 
    } 

    private TextView textRoll; 
    private Random rand = new Random(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     findViewById(R.id.button_roll).setOnClickListener(this); 
     textRoll = (TextView)findViewById(R.id.textview_roll); 
    } 

    @Override 
    public void onDestroy() 
    { 
     findViewById(R.id.button_roll).setOnClickListener(null); 
     textRoll = null; 
     super.onDestroy(); 
    } 

    @Override 
    public void onClick(View v) 
    { 
     int id = v.getId(); 

     if (id == R.id.button_roll) 
     { 
      findViewById(R.id.textview_roll).post(new Roller(20, 100)); 
     } 
    } 
} 
+0

完美!非常感謝。我注意到我找到的.post方法在UI線程中運行。乾杯。 – JohnJ73 2014-09-25 21:38:01

+0

右鍵 - 一個帶有視圖的Runnable會被放入隊列中,當它被檢索到時,它會在主(UI)線程上被調用。 – 2014-09-25 21:41:39

+0

如何使用按鈕單擊'暫停'線程和'恢復'?另外,我該如何「停止」線程? – Si8 2016-12-04 17:14:04

0

您可以使用handler概念:

有幾種方法來更新您的UI和修改視圖,如從UI線程之外的TextView。 A Handler只是一種方法。

下面是一個示例,它允許單個Handler響應各種類型的請求。

private final static int DO_UPDATE_TEXT = 0; 
private final static int DO_THAT = 1; 
private final Handler myHandler = new Handler() { 
    public void handleMessage(Message msg) { 
     final int what = msg.what; 
     switch(what) { 
     case DO_UPDATE_TEXT: doUpdate(); break; 
     case DO_THAT: doThat(); break; 
     } 
    } 
}; 

更新UI在你的函數,也就是現在的UI主題之一:

private void doUpdate() { 
    myTextView.setText("updating.."); 
} 

asynchronous任務,請發送郵件至Handler。有幾種方法可以做到這一點。這可能是最簡單的:

myHandler.sendEmptyMessage(DO_UPDATE_TEXT); 
0

注意到如事先提到的方法。員額後,我有一齣戲,並與這個版本,做同樣的走了過來。你能看出有什麼理由不願意以這種方式運行嗎?

public void ButtonRoll(View view) { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       for(int i = 0; i<50;i++) { 
        try { 
         Thread.sleep(50); 
         final TextView textRoll = (TextView) findViewById(R.id.textview_roll); 
         int n; 
         Random rand = new Random(); 
         n = rand.nextInt(100) + 1; 
         final String roll = String.valueOf(n); 
         textRoll.post(new Runnable() { 
           @Override 
           public void run() { 
            textRoll.setText("Random number is " + roll); 
           } 
         }); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }).start(); 
    }