Android 按钮点击时自动倒计时

Android 按钮点击时自动倒计时,android,countdowntimer,android-handler,Android,Countdowntimer,Android Handler,因此,我正在创建一个训练应用程序,在该程序中,我必须在一段时间后更改按钮上的文本,以表示新设置。单击“开始”按钮后,我希望计时器自动运行,直到完成所有训练集。如果按下“暂停”按钮,当前计时器将停止,直到再次按下“开始”按钮。我想知道该怎么做。我试着在for循环中创建一个新的计时器,但每次运行一次后它就停止了。有什么想法吗?我曾想过使用一个处理程序来做这件事,但我不知道怎么做 package com.dwolford.workoutroutine; import android.os.Count

因此,我正在创建一个训练应用程序,在该程序中,我必须在一段时间后更改按钮上的文本,以表示新设置。单击“开始”按钮后,我希望计时器自动运行,直到完成所有训练集。如果按下“暂停”按钮,当前计时器将停止,直到再次按下“开始”按钮。我想知道该怎么做。我试着在for循环中创建一个新的计时器,但每次运行一次后它就停止了。有什么想法吗?我曾想过使用一个处理程序来做这件事,但我不知道怎么做

package com.dwolford.workoutroutine;

import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;


public class Vertical extends ActionBarActivity {

Handler handler = new Handler();
Button jumpRope;
Button start;
Button pause;
Button back;
EditText timeLeft;
String[] verticalWorkouts = {"JUMP ROPE", "STRETCH", "JUMP ROPE", "STRETCH",
        "SLOW MOTION SQUATS", "STRETCH", "LATERAL JUMPS", "STRETCH", "ALTERNATING JUMP LUNGES", "STRETCH", "TUCK JUMPS", "STRETCH", "TOE RAISES", "STRETCH",
        "SLOW MOTION SQUATS", "STRETCH", "LATERAL JUMPS", "STRETCH", "ALTERNATING JUMP LUNGES", "STRETCH", "TUCK JUMPS", "STRETCH", "TOE RAISES", "STRETCH",
        "SLOW MOTION SQUATS", "STRETCH", "LATERAL JUMPS", "STRETCH", "ALTERNATING JUMP LUNGES", "STRETCH", "TUCK JUMPS", "STRETCH", "TOE RAISES", "STRETCH"};


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


    jumpRope = (Button)findViewById(R.id.jumpRope);
    jumpRope.setFocusableInTouchMode(true);
    jumpRope.requestFocus();


    timeLeft = (EditText)findViewById(R.id.time_left);
    start = (Button)findViewById(R.id.start);
    start.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            for(int i = 0; i < verticalWorkouts.length; i++)
            {
                final int iTemp = i;
                new CountDownTimer(2000, 1000) {

                    public void onTick(long millisUntilFinished) {
                        timeLeft.setText("secs: " + millisUntilFinished / 1000);
                    }

                    int temp = iTemp;
                    public void onFinish() {
                        timeLeft.setText("done!");

                        jumpRope.setText(verticalWorkouts[temp]);
                    }
                }.start();
            }
        }
    });

    pause = (Button)findViewById(R.id.pause);
    pause.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            jumpRope.setText(verticalWorkouts[2]);
        }
    });

    back = (Button)findViewById(R.id.back);
    back.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_vertical, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}
package com.dwolford.workoutroutine;
导入android.os.CountDownTimer;
导入android.os.Handler;
导入android.support.v7.app.ActionBarActivity;
导入android.os.Bundle;
导入android.view.Menu;
导入android.view.MenuItem;
导入android.view.view;
导入android.widget.Button;
导入android.widget.EditText;
公共类垂直扩展ActionBarActivity{
Handler=newhandler();
按钮跳线;
按钮启动;
按钮暂停;
按钮返回;
编辑文本时间限制;
String[]垂直运动={“跳绳”、“伸展”、“跳绳”、“伸展”,
“慢动作下蹲”、“伸展”、“侧向跳跃”、“伸展”、“交替跳跃弓箭步”、“伸展”、“抱膝跳跃”、“伸展”、“脚趾抬高”、“伸展”,
“慢动作下蹲”、“伸展”、“侧向跳跃”、“伸展”、“交替跳跃弓箭步”、“伸展”、“抱膝跳跃”、“伸展”、“脚趾抬高”、“伸展”,
“慢动作下蹲”、“伸展”、“侧跳”、“伸展”、“交替跳跃弓箭步”、“伸展”、“抱膝跳”、“伸展”、“脚趾抬高”、“伸展”};
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_垂直);
跳线=(按钮)findViewById(R.id.跳线);
跳线。设置聚焦到接触模式(真);
jumpRope.requestFocus();
timeLeft=(EditText)findViewById(R.id.time\u左);
开始=(按钮)findViewById(R.id.start);
start.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
对于(int i=0;i
以下是XML:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="WORKOUT: VERTICAL"
    android:id="@+id/title"
    android:height="50dp"
    android:textSize="22dp"
    android:gravity="center_horizontal"
    android:textStyle="bold"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Toe Raises"

    android:state_pressed="true"

    android:id="@+id/toeRaises"
    android:layout_below="@+id/tuckJumps"
    android:background="@drawable/button_gradient"
    android:layout_alignParentLeft="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Tuck Jumps"
    android:id="@+id/tuckJumps"
    android:layout_below="@+id/altJumpLunge"
    android:background="@drawable/button_gradient"
    android:layout_alignParentLeft="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Alternating jump lunges"
    android:id="@+id/altJumpLunge"
    android:layout_below="@+id/latJump"
    android:background="@drawable/button_gradient"
    android:layout_alignParentLeft="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Lateral jumps"
    android:id="@+id/latJump"
    android:layout_below="@+id/button7"
    android:background="@drawable/button_gradient"
    android:layout_alignParentLeft="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Slow motion squats"
    android:id="@+id/button7"
    android:layout_below="@+id/stretch"
    android:background="@drawable/button_gradient"
    android:layout_alignParentLeft="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Stretch"
    android:id="@+id/stretch"
    android:layout_below="@+id/jumpRope"
    android:background="@drawable/button_gradient"
    android:layout_alignParentLeft="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="JUMP ROPE"
    android:id="@+id/jumpRope"
    android:layout_below="@+id/title"
    android:layout_alignParentLeft="true"
    android:background="@drawable/button_gradient"
    android:layout_alignParentStart="true" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="TIME:"
    android:id="@+id/time"
    android:height="50dp"
    android:textSize="22dp"
    android:gravity="center_horizontal"
    android:textStyle="bold"
    android:layout_alignBottom="@+id/jumpRope"
    android:layout_alignRight="@+id/title"
    android:layout_alignEnd="@+id/title" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Sets Left: "
    android:id="@+id/setsLeft"
    android:height="50dp"
    android:textSize="22dp"
    android:gravity="center_horizontal"
    android:textStyle="bold"
    android:layout_below="@+id/toeRaises"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pause"
    android:id="@+id/pause"
    android:background="@drawable/button_gradient"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="start"
    android:id="@+id/start"
    android:layout_alignTop="@+id/pause"
    android:background="@drawable/button_gradient"
    android:layout_centerHorizontal="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="back"
    android:id="@+id/back"
    android:background="@drawable/button_gradient"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true" />

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/editText2"
    android:layout_below="@+id/toeRaises"
    android:layout_toRightOf="@+id/toeRaises"
    android:layout_alignRight="@+id/latJump"
    android:layout_alignEnd="@+id/latJump" />

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/time_left"
    android:layout_below="@+id/time"
    android:layout_alignRight="@+id/back"
    android:layout_alignEnd="@+id/back"
    android:layout_alignLeft="@+id/time"
    android:layout_alignStart="@+id/time" />



在我的应用程序中,我实现了一个处理程序。以下是未经测试的摘录:

private TextView time;
private boolean isPause;
private long startTime;
private long millis;
private long elapsedTime;
private final int MAXTIME = 10000;
private Handler timeHandler = new Handler();
private Runnable timeRunnable = new Runnable(){
    @Override
    public synchronized void run(){
        if(!isPause){
            millis = System.currentTimeMillis() - startTime;
            updateMyTextView();
            checkEnd();
        }
        //here you can add other stuff...
        timeHandler.postDelayed(this, 500); 
}};

@Override
protected void onCreate(Bundle savedInstanceState) {

    //...

    isPause = false;
    startTime = System.currentTimeMillis();
    time = (TextView) findViewById(R.id.timerTextView);
    time.setText("Time: " + String.valueOf(MAXTIME/1000)); //MAXTIME -> how many milliseconds your timer should work overall
    elapsedTime = 0; //buffer for pause

    timeHandler.postDelayed(timeRunnable, 0);        
}

private void updateMyTextView(){
    timerTextView.setText("Time: " + String.valueOf((MAXTIME-millis)/1000));
}

private synchronized void checkEnd(){
    if(millis >= MAXTIME){
        isPause = true;
        timerTextView.setText("Time: OUT OF TIME");
    }
}

private void startAgain(){
    startTime = System.currentTimeMillis();
    time.setText("Time: " + String.valueOf(MAXTIME/1000));
    elapsedTime = 0;
    isPause = false;
}

@Override
public synchronized void onClick(View v) {
    if(v == pause){
        if (isPause) {
            isPause = false;
            SoundManager.getInstance().resume();
            pause.setImageResource(R.drawable.pause);
            startTime = System.currentTimeMillis() - elapsedTime ;
        } else {
            isPause = true;
            SoundManager.getInstance().pause();
            pause.setImageResource(R.drawable.start);
            elapsedTime = System.currentTimeMillis() - startTime;
        }
    }
    //... here you can add buttons for restart
}

@Override
public synchronized void onPause() {
    elapsedTime = System.currentTimeMillis() - startTime;           
    super.onPause();
}

@Override
public synchronized void onResume(){
    super.onResume();
    startTime = System.currentTimeMillis() - elapsedTime ;
}

在Runnable中,我正在更新一个称为millis的时间变量。有一个按钮用于开始/暂停倒计时。如果按下按钮,变量elapsedTime有助于在暂停后恢复正确的时间。如果要重新启动,可以调用startAgain()方法。运行时是用常量MAXTIME指定的。

在我的应用程序中,我实现了一个处理程序。以下是未经测试的摘录:

private TextView time;
private boolean isPause;
private long startTime;
private long millis;
private long elapsedTime;
private final int MAXTIME = 10000;
private Handler timeHandler = new Handler();
private Runnable timeRunnable = new Runnable(){
    @Override
    public synchronized void run(){
        if(!isPause){
            millis = System.currentTimeMillis() - startTime;
            updateMyTextView();
            checkEnd();
        }
        //here you can add other stuff...
        timeHandler.postDelayed(this, 500); 
}};

@Override
protected void onCreate(Bundle savedInstanceState) {

    //...

    isPause = false;
    startTime = System.currentTimeMillis();
    time = (TextView) findViewById(R.id.timerTextView);
    time.setText("Time: " + String.valueOf(MAXTIME/1000)); //MAXTIME -> how many milliseconds your timer should work overall
    elapsedTime = 0; //buffer for pause

    timeHandler.postDelayed(timeRunnable, 0);        
}

private void updateMyTextView(){
    timerTextView.setText("Time: " + String.valueOf((MAXTIME-millis)/1000));
}

private synchronized void checkEnd(){
    if(millis >= MAXTIME){
        isPause = true;
        timerTextView.setText("Time: OUT OF TIME");
    }
}

private void startAgain(){
    startTime = System.currentTimeMillis();
    time.setText("Time: " + String.valueOf(MAXTIME/1000));
    elapsedTime = 0;
    isPause = false;
}

@Override
public synchronized void onClick(View v) {
    if(v == pause){
        if (isPause) {
            isPause = false;
            SoundManager.getInstance().resume();
            pause.setImageResource(R.drawable.pause);
            startTime = System.currentTimeMillis() - elapsedTime ;
        } else {
            isPause = true;
            SoundManager.getInstance().pause();
            pause.setImageResource(R.drawable.start);
            elapsedTime = System.currentTimeMillis() - startTime;
        }
    }
    //... here you can add buttons for restart
}

@Override
public synchronized void onPause() {
    elapsedTime = System.currentTimeMillis() - startTime;           
    super.onPause();
}

@Override
public synchronized void onResume(){
    super.onResume();
    startTime = System.currentTimeMillis() - elapsedTime ;
}

在Runnable中,我正在更新一个称为millis的时间变量。有一个按钮用于开始/暂停倒计时。如果按下按钮,变量elapsedTime有助于在暂停后恢复正确的时间。如果要重新启动,可以调用startAgain()方法。运行时是用常量MAXTIME指定的。

我能想到的另一种方法是让计时器在单独的线程上运行

long lastPauseTime
long currentTime
long elapsedTime
boolean ispused
声明为字段变量。每当按下暂停按钮时,切换
isPaused
。并在线程中实现此伪代码:

while countdownTime > 0: 

    if isPaused:
        lastPauseTime = currentTime
    else: 
        elapsedTime = elapsedTime + (currentTime - lastPauseTime)

    countdownTime = timeLimit - elapsedTime 
    TextView --> display countdownTime

然后通过启动、停止、锻炼类型等功能增强这些功能

我能想到的另一种方法是让计时器在单独的线程上运行

long lastPauseTime
long currentTime
long elapsedTime
boolean ispused
声明为字段变量。每当按下暂停按钮时,切换
isPaused
。并在线程中实现此伪代码:

while countdownTime > 0: 

    if isPaused:
        lastPauseTime = currentTime
    else: 
        elapsedTime = elapsedTime + (currentTime - lastPauseTime)

    countdownTime = timeLimit - elapsedTime 
    TextView --> display countdownTime

然后通过启动、停止、锻炼类型等功能增强这些功能

如果你的问题已被回答,请确保将回答标记为答案。如果你的问题已被回答,请确保将回答标记为答案。