有一个我想在TextView中显示的时钟。
我原本以为有一些很好的功能可以做到这一点,但我找不到任何东西。 我最终实现了自己使用Handler的方式。我问的是,是否有更好(更有效)的方式来显示实时更新时钟?
private Runnable mUpdateClockTask = new Runnable() {
public void run() {
setTime();
mClockHandler.postDelayed(this, 1000);
}
};
这是我的处理程序,它每秒运行一次,然后我的设置时间和日期函数低于
TextView mClockView;
public void setTime() {
Calendar cal = Calendar.getInstance();
int minutes = cal.get(Calendar.MINUTE);
if (DateFormat.is24HourFormat(this)) {
int hours = cal.get(Calendar.HOUR_OF_DAY);
mClockView.setText((hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes));
}
else {
int hours = cal.get(Calendar.HOUR);
mClockView.setText(hours + ":" + (minutes < 10 ? "0" + minutes : minutes) + " " + new DateFormatSymbols().getAmPmStrings()[cal.get(Calendar.AM_PM)]);
}
}
干杯
答案 0 :(得分:38)
更新系统时钟与更新计时器不同。我们谈论的时间是分钟(系统时钟分钟和00秒)。
使用计时器不是正确的方法。它不仅矫枉过正,而且你必须采取一些技巧才能做到正确。
正确的方法(即更新显示时间为HH:mm的TextView)是使用BroadcastReceiver,如下所示:
BroadcastReceiver _broadcastReceiver;
private final SimpleDateFormat _sdfWatchTime = new SimpleDateFormat("HH:mm");
private TextView _tvTime;
@Override
public void onStart() {
super.onStart();
_broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context ctx, Intent intent) {
if (intent.getAction().compareTo(Intent.ACTION_TIME_TICK) == 0)
_tvTime.setText(_sdfWatchTime.format(new Date()));
}
};
registerReceiver(_broadcastReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
}
@Override
public void onStop() {
super.onStop();
if (_broadcastReceiver != null)
unregisterReceiver(_broadcastReceiver);
}
系统将根据系统时钟在每分钟的确切开始时发送此广播事件。不要忘记事先初始化TextView(到当前系统时间),因为很可能你会在一分钟内弹出你的UI,而TextView不会更新,直到下一分钟发生。< / p>
答案 1 :(得分:15)
查看Chronometer和DigitalClock类,它们是TextView类的扩展。他们应该自动做你想要的。如果您需要一些额外的功能,只需查看这些功能的源代码并进行所需的任何更改。
更新:
由于API 17中不推荐使用数字时钟,我建议改为使用Text Clock 。
答案 2 :(得分:4)
我推荐TextClock(来自API 17),也请不要使用DigitalClock(从API 17弃用)因为它会导致MEMORY LEAK并导致Out of Memory Exception。 请将以下代码添加到相应的layout.xml文件
<TextClock
android:id="@+id/textClock1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textColor="#17d409" />
这样可以解决问题,请注意您可以根据需要格式化显示时间,例如以12小时格式显示您可以使用的秒数&#34; android:format12Hour =&#34; hh:mm: ss a&#34;&#34;。
答案 3 :(得分:2)
记住:过早优化是万恶之源。因此,只有在您确定(=已经测量过)您的实施缓慢/低效时才进行优化。
也就是说,更有效的方法可能是通过System.currentTimeMillis()
记录开始时间,然后定期检查并计算分钟差异。
答案 4 :(得分:1)
您可以使用android提供的TextClock小部件
<TextClock
android:id="@+id/textClock"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:format12Hour="hh:mm:ss a"
android:gravity="center_horizontal"
android:textColor="#d41709"
android:textSize="20sp"
android:textStyle="bold" />
它要求最低API级别17
https://developer.android.com/reference/android/widget/TextClock
如果要在另一个文本视图中显示当前时间
您可以使用以下代码段
tClock = (TextClock) findViewById(R.id.textClock1);
tView = (TextView) findViewById(R.id.textview1);
btn = (Button)findViewById(R.id.btnGet);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tView.setText("Time: "+tClock.getText());
}
});
}
答案 5 :(得分:0)
DigitalClock小部件在android api 1中可用,或者在api 17中使用TextClock小部件
首先为这个时钟创建布局:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/clocktext"
android:textStyle="bold"
android:textColor="#ffffff"
android:layout_marginTop="30dp"
android:textSize="50sp"
android:text="2:46"/>
<DigitalClock android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/clock"
android:textStyle="bold"
android:textSize="50sp"
android:visibility="gone"
android:textColor="#ffffff"
/>
</LinearLayout>
在Activity中将textchage监听器添加到DigitalClock,它是textview的子类,因此我们可以添加textchangedkistener来获取更新的时间并根据需要设置textview的时间
chagre = (TextView) mTopView.findViewById(R.id.clocktext);// TextView to display Time
clock = (DigitalClock) mTopView.findViewById(R.id.clock);// DigitalClock With visibility=gone
clock.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {}
@Override
public void afterTextChanged(Editable s) {
chagre.setText(s.toString());//will be called when system clock updataes
}
});