我正在开发我的第一款Android应用,请原谅我的新手。该应用程序是一个倒数计时器,具有默认的起始值,我希望用户可以选择覆盖。
我最接近成功的是添加一个弹出对话框的按钮,用户可以在其中键入新值。计时器在开始倒计时时正确使用新值,但在倒计时期间单击计时器切换按钮时,timer.cancel()不会使数字停止滴答。我已经尝试在Counter类中创建我自己的timerCancel()方法,该方法调用onFinish(),但数字仍在不断变化。
TIA求助。
package com.mypackage.myapp;
/*
* Used tutorial at https://www.youtube.com/watch?v=ZqqP69rJVmg for countdown timer
*/
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import java.util.concurrent.TimeUnit;
public class SprintActivity extends AppCompatActivity {
private DBHelper mydb ;
SharedPreferences prefs = null;
final Context context = this;
ToggleButton toggle;
ImageButton btn_editSprintValue;
TextView textViewTimer;
TextView p, c, t, s;
int iSprintDuration, iSprDefault;
private SoundPool soundPool;
private int soundID;
boolean loaded = false;
String sTitle;
String sCurrWC;
String sTarWC;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sprint);
mydb = new DBHelper(this);
p = (TextView) findViewById(R.id.tv_ProjTitle);
c = (TextView) findViewById(R.id.tv_curr_wc);
t = (TextView) findViewById(R.id.tv_tar_wc);
s = (TextView) findViewById(R.id.tv_sprint_dur);
btn_editSprintValue = (ImageButton) findViewById(R.id.btn_editsprintdur);
//show the project name and the current word count
//First, get the record id from the
//data bundle that's passed in as an "extra"
Bundle extras = getIntent().getExtras();
if (extras != null) {
int projid = extras.getInt("id");
if(projid>0){
Cursor rs = mydb.getProjectData(projid);
rs.moveToFirst();
//now get project title, target word count, and current word count from the db
sTitle = rs.getString(rs.getColumnIndex(DBHelper.PROJECTS_COLUMN_TITLE));
int i = rs.getInt(rs.getColumnIndex(DBHelper.PROJECTS_COLUMN_CURR_WORDCOUNT));
sCurrWC = String.valueOf(i);
i = rs.getInt(rs.getColumnIndex(DBHelper.PROJECTS_COLUMN_TARGET_WORDCOUNT));
sTarWC = String.valueOf(i);
if (!rs.isClosed())
{
rs.close();
}
prefs = this.getSharedPreferences(
"com.mypackage.myapp", Context.MODE_PRIVATE);
iSprDefault = prefs.getInt("default_sprint_len", 45);
//set the title to the project title
p.setText(sTitle);
// now set the current and target word count and sprint duration fields
c.setText(sCurrWC);
t.setText(sTarWC);
s.setText(String.valueOf(iSprDefault));
}
}
//set up the timer toggle button
toggle = (ToggleButton) findViewById(R.id.toggleButton);
textViewTimer = (TextView) findViewById(R.id.timer);
iSprintDuration = 60 * 1000 * iSprDefault;
//When user clicks the toggle, start the timer
toggle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RunTheTimerStuff(v);
}
});
// Set the hardware buttons to control the music
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Load the sound
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
}
});
soundID = soundPool.load(this, R.raw.finished, 1);
}
public void RunTheTimerStuff(View v){
textViewTimer.setText("00:00:00");
final Counter timer = new Counter(iSprintDuration,1000);
if (((ToggleButton) v).isChecked()) {
s.setEnabled(false);
s.setCursorVisible(false);
s.setFocusableInTouchMode(false);
s.setClickable(false);
timer.UpdateTimer();
timer.start();
} else {
s.setEnabled(true);
s.setCursorVisible(true);
s.setFocusableInTouchMode(true);
s.setClickable(true);
timer.timercancel();
textViewTimer.setText("00:00:00");
}
}
public void onClickUpdateSprint (View view) {
//This is where we call the dialog to get the new sprint duration
AlertDialog.Builder alert = new AlertDialog.Builder(this);
final EditText edittext = new EditText(context);
edittext.setInputType(InputType.TYPE_CLASS_NUMBER);
alert.setMessage("Select a number from 5-120 (minutes)");
alert.setTitle("Set a sprint duration for this session");
alert.setView(edittext);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//What ever you want to do with the value
String editTextValue = edittext.getText().toString();
int i = Integer.valueOf(editTextValue);
iSprintDuration = 60 * 1000 * i;
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//do nothing
}
});
alert.show();
}
public class Counter extends CountDownTimer{
long millis;
public Counter(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
millis = millisInFuture;
}
@Override
public void onTick(long millisInFuture) {
millis = millisInFuture;
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
System.out.println(hms);
textViewTimer.setText(hms);
}
public void timercancel(){
onFinish();
}
@Override
public void onFinish() {
textViewTimer.setText("00:00:00");
// Getting the user sound settings
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float actualVolume = (float) audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
// Is the sound loaded already?
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
Log.e("Test", "Played sound");
}
toggle.setChecked(false);
s.setEnabled(true);
s.setClickable(true);
s.setCursorVisible(true);
s.setFocusableInTouchMode(true);
}
public void UpdateTimer() {
millis = (long) iSprintDuration;
}
} //end counter class
} //end activity class
答案 0 :(得分:0)
让我们尝试一些事情。
首先,将新的CountDownTimer实例化为SprintActivity中的全局变量,以及timeRemaining变量,我们暂时可以将其设置为0。 (毫秒)以及起始量的变量。
CountDownTimer timer;
Integer timeRemaining = 0;
Integer startingTime = 1000;
现在,在RunTheTimerStuff(View v)中,改为使用:
timeRemaining = startingTime;
Integer countDownInterval = 1000;
//CountDownTimer(Total Time Milliseconds, count down interval also Milliseconds)
timer = new CountDownTimer(startingTime, countDownInterval) {
public void onTick(long millisUntilFinished) {
timeRemaining -= countDownInterval;
}
public void onFinish() {
//Do stuff here
}
}.start();
要在此活动的任何位置取消计时器,请调用timer.cancel();.这将停止计时器,你剩下的就是timeRemaining。例如,如果它是一个20秒的计时器而你在一秒钟后停止它,则剩余时间应为1000。
要添加到计时器并重新开始,只需添加到开始时间,然后再次调用RunTheTimerStuff(View v)。
startingTime = timeRemaning + theTimeTheyWishToAdd;
RunTheTimerStuff(null);
如果您决定不添加当前时间,而是开始新的时间,请确保重置开始时间。
startingTime = 1000;