У меня есть деятельность, которая оценивает человека, поющего в реальном времени, на опорную дорожку. Я хочу, чтобы, когда человек нажимает кнопку «Практика», на экране появляется обратный отсчет в течение 5 секунд, при этом все компоненты на экране деактивируются. Я также хочу показать обратный отсчет на экране. Идея состоит в том, чтобы иметь прозрачное серое наложение поверх моего изображения Activity
и показывать обратный отсчет. Я думаю о реализации логики с AsyncTask
и CountDownTimer
в Android-SDK. Какими могут быть лучшие способы достижения этой визуализации?Реализация таймера обратного отсчета, налагающего активность
ответ
я, наконец, смог добиться этого без использования CountDownTimer
. Для этого я создал класс, расширяющий AsyncTask
следующим образом:
public class CountdownTask extends AsyncTask<Integer, Integer, Integer> {
private ICountdownView mCountdownView;
private static final String TAG = "CountdownTask";
public CountdownTask(ICountdownView countdownView) {
this.mCountdownView = countdownView;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// Code to set up the timer ...
mCountdownView.initCountdownView();
}
@Override
protected Integer doInBackground(Integer... params) {
// setting the default number of steps ..
int countdownSteps = 5;
// reading the number of steps if mentioned in the parameters
if (params.length >= 1 && params[0] != null) {
countdownSteps = params[0];
}
// setting the default step duration in milliseconds ..
int stepDur = 1000;
// reading the step duration if mentioned in the parameters
if (params.length >= 2 && params[1] != null) {
stepDur = params[1];
}
for (int i = 0; i < countdownSteps; i++) {
publishProgress(countdownSteps - i);
sleep(stepDur);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
mCountdownView.updateCountdownView(values[0]);
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
mCountdownView.destroyCountDownView();
}
private void sleep(int mDelay) {
try {
Thread.sleep(mDelay);
} catch (InterruptedException e) {
Log.e(TAG, e.toString());
}
}
}
Для обновления до пользовательского интерфейса, я создал интерфейс ICountdownView
. Независимо от того, какая активность хочет, обратный отсчет должен реализовать этот интерфейс, а затем инициализировать CountdownTask
с использованием new CountdownTask(this)
, где this
относится к ссылке класса активности. Интерфейс ICountdownView
выглядит следующим образом:
public interface ICountdownView {
void initCountdownView();
void updateCountdownView(int timeLeft);
void destroyCountDownView();
}
В вашей деятельности, вы реализуете все эти методы, с помощью любой анимации вы хотите. В моем случае, на initCountdownView()
, я инициализирую диалог с прозрачным фоном и без заголовка. На каждом updateCountdownView(int timeLeft)
я показываю оставшееся время в диалоговом окне и анимируем его. На экране destroyCountDownView()
, I dismiss()
диалог и продолжайте все, что мне нужно сделать дальше. Надеюсь это поможет!
PS: Вы можете начать CountdownTask
с количеством шагов и продолжительность каждого этапа, указанного в миллисекундах, как:
mCountdownTask.execute(5, 1000);
Это выше заявление делает обратный отсчет для выполнения в 5 этапов с каждым шагом является 1000 миллисекунды (1 секунда). Это также поведение по умолчанию для CountdownTask
в случае, если пользователь не предоставляет никаких аргументов.
пойти на CountDownTimer
, так как он обеспечивает вне коробки тиканье функциональность:
new CountDownTimer (5000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
countDownView.setText((int)(millisUntilFinished/1000) + "sec left");
}
@Override
public void onFinish() {
overlay.setVisibility(GONE);
}
}.start()
Я понимаю эту часть. Я хотел спросить, как реализовать представление. На данный момент я использую «PopupWIndow» с прозрачным фоном над своей деятельностью. Я использую 'CountDownTimer' внутри' doInBackground() 'метода' AsyncTask'. Я решил сделать это, потому что хотел отделить эту логику от своей основной деятельности и повторно использовать ту же самую реализацию таймера обратного отсчета в других местах. Проблема, которую я получаю сейчас, это то, что она показывает мне исключение во время выполнения 'Caused by: java.lang.RuntimeException: не удается создать обработчик внутри потока, который не вызвал Looper.prepare()'. – Swapnil
Я не стал бы запускать CDT из AT, потому что оба они работают в потоках, поэтому это может привести к определенным накладным расходам. Затем вам нужно позаботиться о UI-потоке: в AsyncTask вы можете влиять на основной поток только в методах onPre/PostProcess(). С другой стороны, вы можете сгенерировать свою CDT-реализацию, передав в нее аргумент overlay-view в качестве аргумента конструктора. – injecteer
Да. Спасибо, что намекнул на это. Это помогло! – Swapnil
Хорошая логика bro .. + 1 для этого –