2014-09-25 43 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(); 
    }