I have been trying to create a program that will output a working digital clock that will allow me to quickly access the date and time. I have the code to parse the time, however, I'm having difficulty updating the textview. I have this:
`public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timer = (TextView)findViewById(R.id.timer);
time = new Time();
time.setToNow();
timeString = time.toString();
changeTime = Parser(timeString);
time.setToNow();
timeString = time.toString();
changeTime = Parser(timeString);
timer.setText(changeTime);
}
private String Parser(String time){
String year = time.substring(0, 4);
String month = time.substring(4,6);
String day = time.substring(6, 8);
String hour = time.substring(9,11);
String minute = time.substring(11, 13);
String second = time.substring(13, 15);
String finalTime = hour + ":" + minute + ":" + second + " " + day + " " + month + " " + year;
//String finalTime = second;
return finalTime;
}`
How do I put this in a loop to constantly update the textview.
Thanks for any help you can give me.
Declare a Handler to update the TextView on the UI thread.
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
time = new Time();
time.setToNow();
timeString = time.toString();
changeTime = Parser(timeString);
timer.setText(changeTime);
}
};
Start a TimeTask that will update your TextView
int initialDelay = 1000; //first update in miliseconds
int period = 5000; //nexts updates in miliseconds
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
Message msg = new Message();
mHandler.sendMessage(msg);
}
};
timer.scheduleAtFixedRate(task, initialDelay, period);
You should use a timer thread. You can also simplify your time and date conversions by using Calendar
, and can optimize your String creation by using format
. This example will update your TextView
every second (1000ms):
Timer t = new Timer();
timer = (TextView)findViewById(R.id.timer);
t.scheduleAtFixedRate(new TimerTask()
{
@Override
public void run() {
Calendar c = Calendar.getInstance();
final String finalTime = String.format(Locale.US, "%d:%d:%d %d/%d/%d", c.get(Calendar.HOUR), c.get(Calendar.MINUTE), c.get(Calendar.SECOND), c.get(Calendar.DAY_OF_MONTH), c.get(Calendar.MONTH), c.get(Calendar.YEAR));
runOnUiThread(new Runnable() {
@Override
public void run() {
timer.setText(finalTime);
}
});
}
}, 1000, 1000); //Initial Delay and Period for update (in milliseconds)
This can be done easily with the help of a thread in android but as you want to access the ui so threads won't work help you. you should better choose handlers or timertask
However async tasks also run on Non-ui thread so make an handler inside a timertask..
Timer t=Timer();
t.scheduleAtFixedRate(new TimerTask(new Runnable()
{
public void run(){
Handler h=new Handler(getMainLooper());
h.post(new Runnable(
){public void run(){
//get the time here and set the textview here as here it has access to the main ui
}});
}
}
), long delay, Long period);
Sorry for bad code formatting ...but it will work for you
It is a bad practice to start updating the view with never ending handler messages (try it an look at the CPU level of your process).
The better and more elegant way is to register a BroadcastReceiver
which will trigger the update.
public class Clock extends LinearLayout {
private Calendar mCalendar;
private LinearLayout mLayoutTime;
private TextView mAMPMText;
private TextView mDateText;
private TextView mTimeText;
private View mSendFeedback;
private boolean mAttached;
private final Handler mHandler = new Handler();
SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE, MMM d, yyyy");
SimpleDateFormat timeFormatter = new SimpleDateFormat("h:mm");
public Clock(final Context context, int layoutResourceID, int dateResId, int meResId,int amPmResId) {
super(context);
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(layoutResourceID, null);
addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
mAMPMText = (TextView) view.findViewById(amPmResId);
mTimeText = (TextView) view.findViewById(timeResId);
mDateText = (TextView) view.findViewById(dateResId);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!mAttached) {
mAttached = true;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getContext().registerReceiver(mIntentReceiver, filter, null, mHandler);
}
// NOTE: It's safe to do these after registering the receiver since the receiver always runs
// in the main thread, therefore the receiver can't run before this method returns.
// The time zone may have changed while the receiver wasn't registered, so update the Time
mCalendar = Calendar.getInstance();
// Make sure we update to the current time
onTimeChanged();
updateView();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mAttached) {
getContext().unregisterReceiver(mIntentReceiver);
mAttached = false;
}
}
private void updateView(){
mTimeText.setText(timeFormatter.format(mCalendar.getTime()));
mDateText.setText(dateFormatter.format(mCalendar.getTime()));
mAMPMText.setText(mCalendar.get(Calendar.AM_PM) == 0 ? "AM" : "PM");
}
private void onTimeChanged() {
mCalendar.setTime(new Date());
updateContentDescription(mCalendar);
}
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
String tz = intent.getStringExtra("time-zone");
mCalendar.setTimeZone(TimeZone.getTimeZone(tz));
}
onTimeChanged();
updateView();
}
};
private void updateContentDescription(Calendar calendar) {
setContentDescription(calendar.toString());
}
}
The layout (can be done better)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/layout_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/time_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="true" />
<TextView
android:id="@+id/am_pm_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AM" />
</LinearLayout>
<TextView
android:id="@+id/date_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
来源:https://stackoverflow.com/questions/16153971/updating-textview-with-clock