1

没有错误,编译,没有运行时错误。嘿,我有一个关于 Android 总和的简单问题。我正在做一个简单的求和,代码编译,它在技术上做了它应该做的事情,对数字求和直到它大于 120。但是,我希望输出显示每个总和,因为它通过循环。不幸的是,它只是立即跳到 textview 上的最后一个总和。我尝试使用睡眠函数,等待函数,但最终发生的是它会等待所有循环的时间量,直到总和大于 120,然后输出最终总和。在这种情况下为 4950。在文本视图上显示每个总和的任何建议?

我也尝试使用这行代码,它可以单独显示每个总和,但是,它会立即启动计时器。它不应该这样做。Toast.makeText(MainActivity.this, "SUM:"+sum1, Toast.LENGTH_SHORT).show();

我的简单应用程序的基本目标 1)显示每个总和 2)当总和大于 120 时启动计时器

问题:如何让它在文本视图上单独显示每个总和,而不是跳转到最终总和?

    public void onClick(View v) 

                for(i=0;i<100;i++)
                    {
                        sum1 = sum1 + i;
                            sum.setText("Sum:"+sum1);
                        if(sum1 > 120)

                            {
                            timer.start();
                            }
                    }

    }

感谢您的时间。

4

3 回答 3

2

它“跳”到最后一个的原因是因为单击的行为会在阻塞 UI 线程的同时运行 for 循环。您实际上看不到文本的变化,但它的变化。您可以通过使用TimerTimerTask来完成您需要的工作,这基本上为您创建了一个单独的线程。它还可以处理您需要的延迟。只需在 Timers 执行方法中进行数学运算。

//make sure these are global
int i = 0;
int sum1 = 2;//not really sure where your sum starts so you choose

TimerTask leTask = new TimerTask() {
                public void run() {
                    sum1 = sum1+i;
                    i++; 
                    /*I don't actually remember if you must go back to the main thread
                    * when in the tasks run method. Incase you get an error because
                    * of that then just do that quickly. I have included a link for
                    * you on how to do that if necessary.*/
                    sum.setText("Sum:"+sum1); 
                    if(sum1 > 120){
                        /*Start your actually timer here
                        * and stop execution of leTask by calling the cancel method*/
                    }         
                }
int delay = 0;//you don't really want a delay since you want it immediately after click
int everySecond = 1000;
timer.scheduleAtFixedRate(leTask, 0, everySecond);

请记住,我设置 ti 的方式只是一个示例。当它被取消时,你应该确保你可以访问leTask(或任何你称之为的)。isum1应该是全球性的。delay并且everySecond不必在变量中。我这样做是为了解释他们的所作所为,这样更有意义。我更喜欢这种方法,因为除了更新 TextView 之外,您不必担心 UI 线程的问题。

编辑:您还可以使用来自 的post方法从计时器访问 UI TextView。它看起来像这样:

sum.post(new Runnable() {
    public void run() {
        sum.setText("Sum:"+sum1);   
    });
}

编辑2:


我必须包含此编辑,以便将来遇到此问题的用户彻底了解,因为我刚刚发现Timer并且TimerTask不再成为调度命令等的首选方法。现在应该是ScheduledThreadPoolExecutor。尽管这种情况已经有一段时间了,但在我遇到的问题中并没有真正得到太多报道。无论哪种情况,android 在此处的文档中都有它。字面意思就是第二句。

于 2013-10-25T17:12:59.307 回答
0

事情是onClick()在 UI 线程上运行的。这意味着整个方法必须在 UI 可以再次更新之前完成,因此会突然跳转到最后一个数字。这也是你使用Thread.Sleep(). sleep()在这种情况下适用于 UI 线程,因此整个应用程序将冻结。

如果您希望 TextView 计数,则必须使用AsyncTask。将循环和 a 添加Thread.sleep()doInBackground(),发布进度并将文本设置在onProgressUpdate(). 该链接实际上包含一个很好的示例,应该适合您。

于 2013-10-25T17:11:36.237 回答
0

这是我提出的解决方案:D

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/resultView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/startButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start counting" />

</LinearLayout>

MainActivity.java

public class MainActivity extends Activity implements OnClickListener {

    private static final long SUM_DELAY = 100;

    private TextView mResultView;
    private Button mStartButton;

    private Handler mHandler = new Handler();

    private int mSum = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mResultView  = (TextView) findViewById(R.id.resultView);
        mStartButton = (Button) findViewById(R.id.startButton);

        mStartButton.setOnClickListener(this);
    }

    private Runnable sumTask = new Runnable() {

        @Override
        public void run() {

            mSum += 1;

            if (mSum > 120) {

                mSum = 0;
                mStartButton.setEnabled(true);

                return;
            }

            mResultView.setText(String.valueOf(mSum));

            mHandler.postDelayed(this, SUM_DELAY);
        }
    }; 

    @Override
    public void onClick(View view) {

        if (view.getId() == mStartButton.getId()) {

            mStartButton.setEnabled(false);
            sumTask.run();
        }
    }

}
于 2013-10-25T17:28:58.133 回答