as版本:
例程:timer
关键点:利用runnable和handler配合。
效果:
代码:
activety_main.xml
XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.272" />
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="36dp"
android:layout_marginTop="80dp"
android:text="开始"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_timer" />
<Button
android:id="@+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="停止"
app:layout_constraintStart_toEndOf="@+id/btn_start"
app:layout_constraintTop_toTopOf="@+id/btn_start" />
<Button
android:id="@+id/btn_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="归零"
app:layout_constraintStart_toEndOf="@+id/btn_stop"
app:layout_constraintTop_toTopOf="@+id/btn_stop" />
</androidx.constraintlayout.widget.ConstraintLayout>
mainactivity.java
java
package com.shudu.timer;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
public class MainActivity extends AppCompatActivity {
private TextView tvTimer;
private Button btnStart, btnStop, btnClear;
private long startTime;
private Handler handler = new Handler();
private Runnable timerRunnable;
private boolean isRunning = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
tvTimer = findViewById(R.id.tv_timer);
btnStart = findViewById(R.id.btn_start);
btnStop = findViewById(R.id.btn_stop);
btnClear = findViewById(R.id.btn_clear);
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startTimer();
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopTimer();
}
});
btnClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clearTimer();
}
});
}
private void startTimer() {
if (!isRunning) {
startTime = System.currentTimeMillis();//开始时间为当前时间
isRunning = true;//运行状态标志
timerRunnable = new Runnable() {//runnable
@Override
public void run() {
long elapsedTime = System.currentTimeMillis() - startTime;//运行时间差
int seconds = (int) (elapsedTime / 1000);//计算秒
int minutes = seconds / 60;//计算分
seconds %= 60;//显示分钟后的剩余秒
int hours = minutes / 60;//计算小时
minutes %= 60;//计算显示小时后剩余的分钟数
String timeText = String.format("%02d:%02d:%02d", hours, minutes, seconds);//时分各种显示格式
tvTimer.setText(timeText);//修改textview
if (isRunning) {
handler.postDelayed(this, 1000);//延迟1秒显示
}
}
};
handler.post(timerRunnable);
}
}
private void stopTimer() {
isRunning = false;
}
private void clearTimer() {
isRunning = false;
// startTime=0;
startTime = System.currentTimeMillis();//这行代码什么意思,不写还不行。写成starttime=0也不行。
tvTimer.setText("00:00:00");
}
}
清除显示代码:
private void clearTimer() {
isRunning = false;
startTime=0;
// startTime = System.currentTimeMillis();//这行代码什么意思,不写还不行。写成starttime=0也不行。
tvTimer.setText("00:00:00");
}
starttime=0;或不写都会显示成下图这样:
不是想要的结果,必须写成:
startTime = System.currentTimeMillis();
我也不知道是什么原因,估计是跟延迟显示有关,有懂的可以留言解释一下。