所以我创建了一个锻炼应用程序,我必须在一段时间后更改按钮上的文字以表示新的设置。一旦"开始"单击按钮我想让计时器自动运行,直到完成所有训练集。如果"暂停"按下按钮,当前计时器停止,直到再次按下开始按钮。我想知道如何解决这个问题。我尝试在for循环中每次都创建一个新的计时器,但是在一次运行后它停止了。有什么想法吗?我曾经使用过Handler来做这件事,但我不知道怎么做。
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);
}
}
这是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" />
答案 0 :(得分:0)
在我的应用程序中我实现了一个处理程序。这是一个未经测试的摘录:
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指定。
答案 1 :(得分:0)
我能想到的另一种方法是让计时器在一个单独的线程上运行。
将long lastPauseTime
,long currentTime
,long elapsedTime
和boolean isPaused
声明为字段变量。每按一次暂停按钮,切换isPaused
。并在一个线程中实现这个伪代码:
while countdownTime > 0:
if isPaused:
lastPauseTime = currentTime
else:
elapsedTime = elapsedTime + (currentTime - lastPauseTime)
countdownTime = timeLimit - elapsedTime
TextView --> display countdownTime
然后用启动,停止,运动类型等功能增强这些功能。