android倒计时器取消不会停止倒计时

时间:2015-09-11 01:23:02

标签: android

我正在开发我的第一款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

1 个答案:

答案 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;