开发者

Android: How do I display an updating clock in a TextView

have a clock I want to display in a TextView.

I would have thought there was a few nice functions to do this, but I couldn't find anything. I ended up implementing my own way that uses a Handler. What I'm asking though, is there a better (more efficient) way to display a real time updating clock?

private Runnable mUpdateClockTask = new Runnable() {
   public void run() {
       setTime();
       mClockHandler.postDelayed(this, 1000);
   }
};

That's my handler, which runs every second, and then my set time and date function is below

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开发者_StackOverflow中文版 ? "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)]);
    }
}

Cheers


Updating the system clock is not like updating a chronometer. We talk about the time changed on the minute (system clock minute and 00 seconds).

Using a Timer is not the right way to do this. It's not only overkill, but you must resort to some tricks to make it right.

The right way to do this (ie. update a TextView showing the time as HH:mm) is to use BroadcastReceiver like this :

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);
}

The system will send this broadcast event at the exact beginning of every minutes based on system clock. Don't forget however to initialize your TextView beforehand (to current system time) since it is likely you will pop your UI in the middle of a minute and the TextView won't be updated until the next minute happens.


Check out the Chronometer and DigitalClock classes, which are extensions of the TextView class. They should automatically do what you're looking for. If you need some additional functionality, just take a look at the source code for those and make any changes you need.

UPDATE:

Since digital clock is deprecated in API 17, I would recommend to use Text Clock instead.


I recommend TextClock (From API 17), also please dont use DigitalClock (Deprecated from API 17) as it will cause MEMORY LEAK and will lead to Out of Memory Exception. Please add the following piece of code to corresponding layout.xml file

 <TextClock
   android:id="@+id/textClock1"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:gravity="center_horizontal"
   android:textColor="#17d409" />

This will do the trick, also please note that you can format the displaying time as required for example for getting in 12 hour format with seconds you can use "android:format12Hour="hh:mm:ss a"".


You can use TextClock widget provided by android

<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" />

it requires minimum API level 17

https://developer.android.com/reference/android/widget/TextClock

if you want the current time in another text view

you can use the below code snippet

 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());
            }
        });
    }


Remember: premature optimization is the root of all evil. So only optimize when you are sure (=have measured it) that your implementation is slow/inefficient.

That said, a more efficient method would probably be to record start time via System.currentTimeMillis() and then periodically check it and calculate difference in minutes.


DigitalClock widget is available in android api 1 or use TextClock widget in api 17

create layout for clock like this first:

<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>       

in Activity add textchage listener to the DigitalClock its a subclass of textview thus we can add textchangedkistener to get the updated time and set the time to your textview as you want

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

        }
    });
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜