我正在寻找一种方法让 Android 中的 Chronometer(最好是 1.6 及更高版本)在计数时显示十分之一秒。
是否有可能做到这一点?如果没有,是否有一个免费的(最好是开源的)库可以做同样的事情?失败了我会写自己的,但我宁愿使用别人的!
我正在寻找一种方法让 Android 中的 Chronometer(最好是 1.6 及更高版本)在计数时显示十分之一秒。
是否有可能做到这一点?如果没有,是否有一个免费的(最好是开源的)库可以做同样的事情?失败了我会写自己的,但我宁愿使用别人的!
Android 的默认计时器小部件不支持毫秒格式。
我修改了 Chronometer 小部件源代码以显示毫秒。从github下载。
是否有可能做到这一点?
并不真地。您可以传递一个显示十分之一秒的格式字符串,但它Chronometer
本身仅每秒更新一次。更新频率已包含在代码中。
如果没有,是否有一个免费的(最好是开源的)库可以做同样的事情?
Chronometer
源代码在 Apache 许可证 2.0下可用,因此您可以对其进行修改以适应。找到所有出现的1000
并将它们更改为100
,您可能已经完成了大部分的工作。
请记住,这Chronometer
可以在活动中使用,但不能在应用小部件中使用,因为View
应用小部件框架不支持自定义类。
我创建了一个在Activity
. 这个新类是 AndroidCountDownTimer
类的扩展(添加实现的方法)
在构造函数中,您可以添加以毫秒为单位的持续时间,并将间隔添加为 1/10 秒,即 100 毫秒。在该onTick
方法中,命令在给定的持续时间内每 1/100 秒执行一次。那应该行得通。
TimeCounter是一个完全一样的库。当您暂停/恢复您的秒表时,您不必担心增加和减少时间。我相信这会让你开心。
package ar.com.magiapensada.apps.dayoftheweek;
import androidx.appcompat.app.AppCompatActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
public static final int NANOSECONDS_CONVERT = 1000000000;
public static final int MICROSECONDS_CONVERT = 1000;
public static final int SEXAGESIMA_CONVERT = 60;
public static final int SEXAGESIMA_FORMAT_CONVERT = 2;
public static final String BROADCAST_TIME_UPDATE = "BROADCAST_TIME_UPDATE";
private Button start;
private TextView tiempo;
private long inicio;
private Long terminado=null;
private boolean running=false;
private Button stop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.tiempo = (TextView) findViewById(R.id.tiempo);
this.start = (Button) findViewById(R.id.start);
this.stop = (Button) findViewById(R.id.stop);
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent intent) {
String action = intent.getAction();
if (action.equals(BROADCAST_TIME_UPDATE)) {
if ( terminado != null){
String cronometro = getCronometroValue(terminado);
tiempo.setText(cronometro);
terminado=null;
}else{
String cronometro = getCronometroValue(System.nanoTime());
tiempo.setText(cronometro);
}
}
}
};
registerReceiver(broadcastReceiver, new IntentFilter(BROADCAST_TIME_UPDATE));
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MainActivity.this.inicio = System.nanoTime();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
running=true;
terminado=null;
while(running){
sendBroadcast();
}
sendBroadcast();
}
});
t.start();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
terminado = System.nanoTime();
running=false;
}
});
}
private void sendBroadcast() {
Intent intent = new Intent(BROADCAST_TIME_UPDATE);
MainActivity.this.sendBroadcast(intent);
}
private String getCronometroValue(long actual) {
long dif = actual - MainActivity.this.inicio;
long segundos = dif/ NANOSECONDS_CONVERT;
long mili = dif - (segundos*NANOSECONDS_CONVERT);
mili = mili/ MICROSECONDS_CONVERT;
long minutos = segundos / SEXAGESIMA_CONVERT;
segundos = segundos % SEXAGESIMA_CONVERT;
String segString = formatSexagesima(segundos);
String minutosString = formatSexagesima(minutos);
String cronometro = minutosString + ":" + segString + ":" + mili;
return cronometro;
}
private String formatSexagesima(long value ){
return String.format("%0" + SEXAGESIMA_FORMAT_CONVERT + "d", value);
}
}
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tiempo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start" />
<Button
android:id="@+id/stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
经过大量的研究,我找到了方法。我不知道它是否有效,因为事实是模拟器在大约 10 秒后崩溃,但在手机上它运行得很好,这对我有用。它看起来像这样:
import android.os.Handler;
public class Chronometer extends Activity {
private Handler mHandler = new Handler();
public void actions() {
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 1); //1 is the number of milliseconds you want the text to be updated
}
Runnable mUpdateTimeTask = new Runnable() {
public void run() {
i++;
txt.setText(formatTime(i)); // formatTime is just for make it readable in HH:MM:SS:MS, but I assume you already have this
mHandler.postDelayed(this, 1);
}
};
}