如何在我的按钮启用的同时进行倒计时 show/start?
How do I make a CountDown show/start at the same moment my Button gets enabled?
"How do I make a CountDown show at the same moment my Button gets enabled ?"
有关按钮的其他信息:按钮作业是通过在 Textview 中显示的字符串数组单击 5 次,然后禁用 5 秒以再次执行相同的任务。
所以 ..我想要一个 CountDown 来直观地显示这 5 秒(启用按钮的时间)倒计时供用户查看。
遗憾的是,我不知道如何将我的 Button 与 CountDown 连接以让它知道它应该在 Button 启用的特定时间倒计时。
我还希望每次启用按钮时都启动倒计时。
我调查了 https://developer.android.com/reference/android/os/CountDownTimer
但它似乎没有针对该特定情况的解决方案。
这就是我现在的按钮代码:
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (currentnumber == list.length) {
currentnumber = 0;
}
if (Curclicks == mod - 1) {
next_button.setEnabled(false);
display.setText(list[currentnumber]);
currentnumber++;
handler.postDelayed(new Runnable() {
@Override
public void run() {
//the button will unlock after the delay specified
next_button.setEnabled(true);
Curclicks = 0;
}
}, delay);
} else {
display.setText(list[currentnumber]);
currentnumber++;
}
Curclicks++;
}
});
UI线程代码能解决吗? :
private void runThread() {
new Thread() {
public void run() {
while (delay == 5000) { //delay = 5000 ( 5 secs)
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
timer.setText("" + delay);//timer=TxtView
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
这个函数应该做你想做的,只要调用它到 OnClickListener
public void countDown(Button yourBtn) {
new Thread() {
public void run() {
try {
int second = 10;
for (int i = second; i >= 1; i--) {
int finalI = i;
yourBtn.post(new Runnable() {
@Override
public void run() {
yourBtn.setText(String.valueOf(finalI))
}
});
Thread.sleep(1000); // Change text every 1s
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
这是一个示例,说明如何使用 Handler
的 postDelayed()
方法创建倒计时。我故意让代码有点冗长,这样你就可以一步一步地通过它来了解发生了什么。
创建一些 class 变量和常量。
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
COUNT_DOWN_FINISH
设置为 5000 --> 5 秒。但可以更改为您需要的任何内容。我还使用 COUNT_DOWN_TICKS
设置为 100 --> 0.1 秒,以防万一你想显示更精确的倒计时。
从您的 OnClick()
方法调用 startCountDown()
开始倒计时。
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
}
为了正确处理 Runnable
,您需要从 onPause()
方法中调用 releaseCountDownHandler()
。这只是一个简短的运行Thread
,但仍然不容忽视
与 Thread.sleep()
方法相比,我更喜欢使用 postDelay()
方法的 Handler
-- 让任何线程进入休眠状态的做法令人不安。另请注意,习惯使用“>=”而不是“==”检查经过的时间条件是一个好主意,具体取决于实现(例如,您使用 SystemClock.elapsedRealtime()
代替)条件可能会错过确切的时间价值!
编辑
在 Activity
class 定义的某处(在本例中我将其称为 MainActivity
),您需要声明一些变量。由于它们是在 class 内部定义的,而不是在方法内部定义的,因此它们被称为 "class variables" 并且在定义 "private".[=36 时它们具有整个 class 的范围=]
public class MainActivity extends AppCompatActivity {
//class variables
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
....
}
您可能已经在 MainActivity
class 的 onCreate()
方法中声明了 onClick()
方法。所以只需添加以下代码:
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCountDown();
}
我提供的所有其他内容都是 MainActivity
class 中的方法...不在任何其他方法中。所以在 onCreate()
方法下面添加我之前发布的所有方法。
它将看起来像这样:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
//class variables
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// you must compensate for the actual layout for your activity
setContentView(R.layout.activity_main);
// you must compensate for the actual id of the TextView
timer = findViewById(R.id.tvTimer);
// you must compensate for the actual id of the Button
next_button = findViewById(R.id.btnNext);
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCountDown();
}
});
}
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
}
}
这段代码就像我上面的代码,只是这段代码引入了一个 "click counter"。我引入了一个新的 class 变量来跟踪按钮被点击的次数。我还引入了一个名为 "NUMBER_OF_BUTTON_CLICKS" 的新常量,它作为点击次数的上限。
用户现在可以点击按钮(在本例中)5 次。在第五次单击时,满足触发 startCountDown
方法的条件,按钮将禁用 5 秒。
public class MainActivity extends AppCompatActivity {
//Constant values
private static final String TAG = MainActivity.class.getSimpleName();
private static final int NUMBER_OF_BUTTON_CLICKS = 5;
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
//class variables
private int howManyClicks = 0;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
private TextView clicks;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// you must compensate for the actual layout for your activity
setContentView(R.layout.activity_main);
// you must compensate for the actual id of the TextView
timer = findViewById(R.id.tvTimer);
// Use this only if you want to display the number of clicks
// you might need to add this TextView if you want to display the number of clicks
clicks = findViewById(R.id.tvClicks);
// you must compensate for the actual id of the Button
next_button = findViewById(R.id.btnNext);
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
howManyClicks++;
if(howManyClicks >= NUMBER_OF_BUTTON_CLICKS){
startCountDown();
}
//Add this only if you want to see how many clicks were made
String myClicks = String.valueOf(howManyClicks);
clicks.setText(myClicks)
}
});
}
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
// reset the clicks counter
howManyClicks = 0;
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
//Add this only if you want to see how many clicks were made
String myClicks = String.valueOf(howManyClicks);
clicks.setText(myClicks)
}
}
"How do I make a CountDown show at the same moment my Button gets enabled ?"
有关按钮的其他信息:按钮作业是通过在 Textview 中显示的字符串数组单击 5 次,然后禁用 5 秒以再次执行相同的任务。
所以 ..我想要一个 CountDown 来直观地显示这 5 秒(启用按钮的时间)倒计时供用户查看。
遗憾的是,我不知道如何将我的 Button 与 CountDown 连接以让它知道它应该在 Button 启用的特定时间倒计时。
我还希望每次启用按钮时都启动倒计时。
我调查了 https://developer.android.com/reference/android/os/CountDownTimer 但它似乎没有针对该特定情况的解决方案。
这就是我现在的按钮代码:
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (currentnumber == list.length) {
currentnumber = 0;
}
if (Curclicks == mod - 1) {
next_button.setEnabled(false);
display.setText(list[currentnumber]);
currentnumber++;
handler.postDelayed(new Runnable() {
@Override
public void run() {
//the button will unlock after the delay specified
next_button.setEnabled(true);
Curclicks = 0;
}
}, delay);
} else {
display.setText(list[currentnumber]);
currentnumber++;
}
Curclicks++;
}
});
UI线程代码能解决吗? :
private void runThread() {
new Thread() {
public void run() {
while (delay == 5000) { //delay = 5000 ( 5 secs)
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
timer.setText("" + delay);//timer=TxtView
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
这个函数应该做你想做的,只要调用它到 OnClickListener
public void countDown(Button yourBtn) {
new Thread() {
public void run() {
try {
int second = 10;
for (int i = second; i >= 1; i--) {
int finalI = i;
yourBtn.post(new Runnable() {
@Override
public void run() {
yourBtn.setText(String.valueOf(finalI))
}
});
Thread.sleep(1000); // Change text every 1s
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
这是一个示例,说明如何使用 Handler
的 postDelayed()
方法创建倒计时。我故意让代码有点冗长,这样你就可以一步一步地通过它来了解发生了什么。
创建一些 class 变量和常量。
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
COUNT_DOWN_FINISH
设置为 5000 --> 5 秒。但可以更改为您需要的任何内容。我还使用 COUNT_DOWN_TICKS
设置为 100 --> 0.1 秒,以防万一你想显示更精确的倒计时。
从您的 OnClick()
方法调用 startCountDown()
开始倒计时。
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
}
为了正确处理 Runnable
,您需要从 onPause()
方法中调用 releaseCountDownHandler()
。这只是一个简短的运行Thread
,但仍然不容忽视
与 Thread.sleep()
方法相比,我更喜欢使用 postDelay()
方法的 Handler
-- 让任何线程进入休眠状态的做法令人不安。另请注意,习惯使用“>=”而不是“==”检查经过的时间条件是一个好主意,具体取决于实现(例如,您使用 SystemClock.elapsedRealtime()
代替)条件可能会错过确切的时间价值!
编辑
在 Activity
class 定义的某处(在本例中我将其称为 MainActivity
),您需要声明一些变量。由于它们是在 class 内部定义的,而不是在方法内部定义的,因此它们被称为 "class variables" 并且在定义 "private".[=36 时它们具有整个 class 的范围=]
public class MainActivity extends AppCompatActivity {
//class variables
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
....
}
您可能已经在 MainActivity
class 的 onCreate()
方法中声明了 onClick()
方法。所以只需添加以下代码:
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCountDown();
}
我提供的所有其他内容都是 MainActivity
class 中的方法...不在任何其他方法中。所以在 onCreate()
方法下面添加我之前发布的所有方法。
它将看起来像这样:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
//class variables
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// you must compensate for the actual layout for your activity
setContentView(R.layout.activity_main);
// you must compensate for the actual id of the TextView
timer = findViewById(R.id.tvTimer);
// you must compensate for the actual id of the Button
next_button = findViewById(R.id.btnNext);
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCountDown();
}
});
}
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
}
}
这段代码就像我上面的代码,只是这段代码引入了一个 "click counter"。我引入了一个新的 class 变量来跟踪按钮被点击的次数。我还引入了一个名为 "NUMBER_OF_BUTTON_CLICKS" 的新常量,它作为点击次数的上限。
用户现在可以点击按钮(在本例中)5 次。在第五次单击时,满足触发 startCountDown
方法的条件,按钮将禁用 5 秒。
public class MainActivity extends AppCompatActivity {
//Constant values
private static final String TAG = MainActivity.class.getSimpleName();
private static final int NUMBER_OF_BUTTON_CLICKS = 5;
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
//class variables
private int howManyClicks = 0;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
private TextView clicks;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// you must compensate for the actual layout for your activity
setContentView(R.layout.activity_main);
// you must compensate for the actual id of the TextView
timer = findViewById(R.id.tvTimer);
// Use this only if you want to display the number of clicks
// you might need to add this TextView if you want to display the number of clicks
clicks = findViewById(R.id.tvClicks);
// you must compensate for the actual id of the Button
next_button = findViewById(R.id.btnNext);
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
howManyClicks++;
if(howManyClicks >= NUMBER_OF_BUTTON_CLICKS){
startCountDown();
}
//Add this only if you want to see how many clicks were made
String myClicks = String.valueOf(howManyClicks);
clicks.setText(myClicks)
}
});
}
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
// reset the clicks counter
howManyClicks = 0;
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
//Add this only if you want to see how many clicks were made
String myClicks = String.valueOf(howManyClicks);
clicks.setText(myClicks)
}
}