2011-11-29 39 views
14

Opracowałem Count Down Counter i nie jestem pewien, jak zatrzymać i wznowić timer, gdy jest kliknięty widok tekstu dla timera. Kliknij, aby rozpocząć, a następnie kliknij ponownie, aby wstrzymać i wznowić, kliknij ponownie tekst widoku zegara.Android: Jak zatrzymać i wznowić licznik odliczania?

To jest mój kod:

Timer = (TextView) this.findViewById(R.id.time); //TIMER 
    Timer.setOnClickListener(TimerClickListener); 
    counter = new MyCount(600000, 1000); 
}//end of create 

private OnClickListener TimerClickListener = new OnClickListener() { 
    public void onClick(View v) { 
     updateTimeTask(); 
    } 

    private void updateTimeTask() { 
     if (decision == 0) { 
      counter.start(); 
      decision = 1; 
     } else if (decision == 2) { 
      counter.onResume1(); 
      decision = 1; 
     } else { 
      counter.onPause1(); 
      decision = 2; 
     }//end if 
    } 

    ; 
}; 

class MyCount extends CountDownTimer { 
    public MyCount(long millisInFuture, long countDownInterval) { 
     super(millisInFuture, countDownInterval); 
    }//MyCount 

    public void onResume1() { 
     onResume(); 
    } 

    public void onPause1() { 
     onPause(); 
    } 

    public void onFinish() { 
     Timer.setText("00:00"); 
     p1++; 
     if (p1 <= 4) { 
      TextView PScore = (TextView) findViewById(R.id.pscore); 
      PScore.setText(p1 + ""); 
     }//end if 
    }//finish 

    public void onTick(long millisUntilFinished) { 
     Integer milisec = new Integer(new Double(millisUntilFinished).intValue()); 
     Integer cd_secs = milisec/1000; 

     Integer minutes = (cd_secs % 3600)/60; 
     Integer seconds = (cd_secs % 3600) % 60; 

     Timer.setText(String.format("%02d", minutes) + ":" 
       + String.format("%02d", seconds)); 
     ///long timeLeft = millisUntilFinished/1000; 
     /}//on tick 
}//class MyCount 

protected void onResume() { 
    super.onResume(); 
    //handler.removeCallbacks(updateTimeTask); 
    //handler.postDelayed(updateTimeTask, 1000); 
}//onResume 

@Override 
protected void onPause() { 
    super.onPause(); 
    //do stuff 
}//onPause 
+0

To pozwoli Ci surelyhelp http://stackoverflow.com/questions/3510433/countdown-timer-required-on-android –

+0

http: // developer. android.com/reference/android/os/CountDownTimer.html –

+0

Czy muszę używać crona do wstrzymywania i wznawiania? – Mineko

Odpowiedz

21
/* 
* Copyright (C) 2010 Andrew Gainer 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

// Adapted from Android's CountDownTimer class 

package com.cycleindex.multitimer; 

import android.os.Handler; 
import android.os.Message; 
import android.os.SystemClock; 

/** 
* Schedule a countdown until a time in the future, with 
* regular notifications on intervals along the way. 
* 
    * The calls to {@link #onTick(long)} are synchronized to this object so that 
* one call to {@link #onTick(long)} won't ever occur before the previous 
* callback is complete. This is only relevant when the implementation of 
* {@link #onTick(long)} takes an amount of time to execute that is significant 
* compared to the countdown interval. 
*/ 
public abstract class CountDownTimerWithPause { 

    /** 
    * Millis since boot when alarm should stop. 
    */ 
    private long mStopTimeInFuture; 

    /** 
    * Real time remaining until timer completes 
    */ 
    private long mMillisInFuture; 

    /** 
    * Total time on timer at start 
    */ 
    private final long mTotalCountdown; 

    /** 
    * The interval in millis that the user receives callbacks 
    */ 
    private final long mCountdownInterval; 

    /** 
    * The time remaining on the timer when it was paused, if it is currently paused; 0 otherwise. 
    */ 
    private long mPauseTimeRemaining; 

    /** 
    * True if timer was started running, false if not. 
    */ 
    private boolean mRunAtStart; 

    /** 
    * @param millisInFuture The number of millis in the future from the call 
    * to {@link #start} until the countdown is done and {@link #onFinish()} 
    * is called 
    * @param countDownInterval The interval in millis at which to execute 
    * {@link #onTick(millisUntilFinished)} callbacks 
    * @param runAtStart True if timer should start running, false if not 
    */ 
    public CountDownTimerWithPause(long millisOnTimer, long countDownInterval, boolean runAtStart) { 
     mMillisInFuture = millisOnTimer; 
     mTotalCountdown = mMillisInFuture; 
     mCountdownInterval = countDownInterval; 
     mRunAtStart = runAtStart; 
    } 

    /** 
    * Cancel the countdown and clears all remaining messages 
    */ 
    public final void cancel() { 
     mHandler.removeMessages(MSG); 
    } 

    /** 
    * Create the timer object. 
    */ 
    public synchronized final CountDownTimerWithPause create() { 
     if (mMillisInFuture <= 0) { 
      onFinish(); 
     } else { 
      mPauseTimeRemaining = mMillisInFuture; 
     } 

     if (mRunAtStart) { 
      resume(); 
     } 

     return this; 
    } 

    /** 
    * Pauses the counter. 
    */ 
    public void pause() { 
    if (isRunning()) { 
     mPauseTimeRemaining = timeLeft(); 
     cancel(); 
    } 
    } 

    /** 
    * Resumes the counter. 
    */ 
    public void resume() { 
    if (isPaused()) { 
     mMillisInFuture = mPauseTimeRemaining; 
     mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture; 
      mHandler.sendMessage(mHandler.obtainMessage(MSG)); 
     mPauseTimeRemaining = 0; 
    } 
    } 

    /** 
    * Tests whether the timer is paused. 
    * @return true if the timer is currently paused, false otherwise. 
    */ 
    public boolean isPaused() { 
    return (mPauseTimeRemaining > 0); 
    } 

    /** 
    * Tests whether the timer is running. (Performs logical negation on {@link #isPaused()}) 
    * @return true if the timer is currently running, false otherwise. 
    */ 
    public boolean isRunning() { 
    return (! isPaused()); 
    } 

    /** 
    * Returns the number of milliseconds remaining until the timer is finished 
    * @return number of milliseconds remaining until the timer is finished 
    */ 
    public long timeLeft() { 
    long millisUntilFinished; 
    if (isPaused()) { 
     millisUntilFinished = mPauseTimeRemaining; 
    } else { 
     millisUntilFinished = mStopTimeInFuture - SystemClock.elapsedRealtime(); 
     if (millisUntilFinished < 0) millisUntilFinished = 0; 
    } 
    return millisUntilFinished; 
    } 

    /** 
    * Returns the number of milliseconds in total that the timer was set to run 
    * @return number of milliseconds timer was set to run 
    */ 
    public long totalCountdown() { 
    return mTotalCountdown; 
    } 

    /** 
    * Returns the number of milliseconds that have elapsed on the timer. 
    * @return the number of milliseconds that have elapsed on the timer. 
    */ 
    public long timePassed() { 
    return mTotalCountdown - timeLeft(); 
    } 

    /** 
    * Returns true if the timer has been started, false otherwise. 
    * @return true if the timer has been started, false otherwise. 
    */ 
    public boolean hasBeenStarted() { 
    return (mPauseTimeRemaining <= mMillisInFuture); 
    } 

    /** 
    * Callback fired on regular interval 
    * @param millisUntilFinished The amount of time until finished 
    */ 
    public abstract void onTick(long millisUntilFinished); 

    /** 
    * Callback fired when the time is up. 
    */ 
    public abstract void onFinish(); 


    private static final int MSG = 1; 


    // handles counting down 
    private Handler mHandler = new Handler() { 

     @Override 
     public void handleMessage(Message msg) { 

      synchronized (CountDownTimerWithPause.this) { 
       long millisLeft = timeLeft(); 

       if (millisLeft <= 0) { 
        cancel(); 
        onFinish(); 
       } else if (millisLeft < mCountdownInterval) { 
        // no tick, just delay until done 
        sendMessageDelayed(obtainMessage(MSG), millisLeft); 
       } else { 
        long lastTickStart = SystemClock.elapsedRealtime(); 
        onTick(millisLeft); 

        // take into account user's onTick taking time to execute 
        long delay = mCountdownInterval - (SystemClock.elapsedRealtime() - lastTickStart); 

        // special case: user's onTick took more than mCountdownInterval to 
        // complete, skip to next interval 
        while (delay < 0) delay += mCountdownInterval; 

        sendMessageDelayed(obtainMessage(MSG), delay); 
       } 
      } 
     } 
    }; 
} 

Źródło: This Gist.

+0

not found: @ gdzie jest link, dlaczego jest akceptowany –

+0

jak widzisz link został dodany jakiś czas temu i mógł się nie zgodzić – hexin

+0

podać inny link lub możesz wkleić swój kod. –

7

No nie ma API, aby wstrzymać lub wznowić. Co należy zrobić, to timer i zapisać czas pozostały w zmiennej. Po ponownym naciśnięciu przycisku wznowienia uruchom ponownie timer z wartością ze zmiennej.


Wiesz, że Chronometers może Cię zainteresować.

+0

Hmm, czy muszę użyć savedInstanceState, aby zachować pozostały czas? lub użyłbym tego: /// longtimeLeft = millisUntilFinished/1000; z mojego kodu? dzięki – Mineko

+0

Jeśli wiesz, że twoja aktywność zawierająca timer jest [zniszczona i ponownie utworzona, to tak, musisz zapisać wartość timera w "savedInstanceState"] (http://stackoverflow.com/a/151940/68805) – Reno

+0

Sorry Im nowy w programowaniu Android.Jak zapisałbym wartość timera za pomocą savedInstanceState? – Mineko

8

Ładny i prosty sposób stworzyć Pause/Resume dla CountDownTimer jest stworzenie odrębnego sposobu zaprogramowania rozpocząć, pauzy i CV następująco :

public void timerStart(long timeLengthMilli) { 
     timer = new CountDownTimer(timeLengthMilli, 1000) { 

      @Override 
      public void onTick(long milliTillFinish) { 
       milliLeft=milliTillFinish; 
       min = (milliTillFinish/(1000*60)); 
       sec = ((milliTillFinish/1000)-min*60); 
       clock.setText(Long.toString(min)+":"+Long.toString(sec)); 
       Log.i("Tick", "Tock"); 
      } 
     } 
     timer.start(); 

TimerStart ma długi parametr, ponieważ zostanie ponownie użyty przez resume() metoda poniżej. Pamiętaj, aby przechowywać swój milliTillFinished (powyżej jako milliLeft), abyś mógł go przesłać w swojej metodzie wznowienia(). Wstrzymać i wznowić metod poniżej odpowiednio:

public void timerPause() { 
     timer.cancel(); 
    } 

    private void timerResume() { 
     Log.i("min", Long.toString(min)); 
     Log.i("Sec", Long.toString(sec)); 
     timerStart(milliLeft); 
    } 

Oto kod dla przycisku FYI:

startPause.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       if(startPause.getText().equals("Start")){ 
        Log.i("Started", startPause.getText().toString()); 
        startPause.setText("Pause"); 
        timerStart(15*1000); 
       } else if (startPause.getText().equals("Pause")){ 
        Log.i("Paused", startPause.getText().toString()); 
        startPause.setText("Resume"); 
        timerPause(); 
       } else if (startPause.getText().equals("Resume")){ 
        startPause.setText("Pause"); 
        timerResume(); 
       } 
1

Można spróbować użyć Hourglass

Hourglass hourglass = new Hourglass(50000, 1000) { 
     @Override 
     public void onTimerTick(long timeRemaining) { 
      // Update UI 
      Toast.show(MainActivity.this, String.valueOf(timeRemaining), Toast.LENGTH_SHORT).show(); 
     } 

     @Override 
     public void onTimerFinish() { 
      // Timer finished 
      Toast.show(MainActivity.this, "Timer finished", Toast.LENGTH_SHORT).show(); 


     } 
    }; 

Korzystając hourglass.startTimer();, aby uruchomić stoper.

Posiada metody pomocnicze umożliwiające wstrzymanie i wznowienie licznika czasu.

hourglass.pauseTimer(); 

I

hourglass.resumeTimer(); 
+0

Działa to świetnie. – piddler