Table of Contents
Article directory
- Table of contents
- Timer + TimerTask implements digital clock
-
- 1. Topic
- 2. Structural analysis
- 3. Module mind map
- 4. Layout
-
- ⑴ view
- ⑵ Navigation bar LOGO
- ⑶ Android seven-segment digital tube font
- ⑷ Code
- 5. Activity
-
- ⑴ Private member variables
- ⑵ Custom initialization function
- ⑶ Navigation bar module
- ⑷ Background module
- ⑸ Clock module
- ⑹onCreate
- 6. Final effect
- 7. Summary
-
- ⑴ String. format() Warning
- ⑵Android code naming convention
Timer + TimerTask implements digital clock
1. Title
?Timer
+ TimerTask
realize digital clock.
? Expected final effect:
2. Structural analysis
? This assignment is mainly divided into 3 major modules: Navigation Bar, Background, Clock.
? Of course, there are many small modules related to these three modules.
3. Module mind map
4. Layout
? Android development should first design the page layout (activity_my_digital_clock.xml).
? Layout id
: cl_wzy_digitalclock
.
⑴View
? Mainly 6 TextView
of the clock module:
⑵ Navigation bar LOGO
? Found the clock LOGO resources on this website: DS-Digital Font | dafont.com.
? And imported the image resource icon_clock.png into res/drawable.
? At the same time, the corresponding clock.xml file was written and changed to white to match the background color of the navigation bar.
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <bitmap android:src="@drawable/icon_clock" android:tint="@color/white" /> </item> </layer-list>
⑶Android seven-segment digital tube font
? Found font resources on this website: Search results for Clock – Flaticon.
? And imported the font resource ds_digi.TTF into the res/font folder.
? Then use the font in the component of the xml file as follows.
android:fontFamily="@font/ds_digi"
⑷ Code
<?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/cl_wzy_digitalclock" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MyDigitalClockActivity"> <TextView android:id="@ + id/tv_time_hmin" android:layout_width="296dp" android:layout_height="131dp" android:fontFamily="@font/ds_digi" android:gravity="center" android:text="00:00" android:textSize="130sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.139" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.305" /> <TextView android:id="@ + id/tv_week" android:layout_width="50dp" android:layout_height="36dp" android:layout_marginTop="4dp" android:text="Week" android:textSize="20sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.243" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@ + id/tv_time_hmin" app:layout_constraintVertical_bias="0.007" /> <TextView android:id="@ + id/tv_AMorPM" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="13dp" android:text="AM" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toEndOf="@ + id/tv_time_hmin" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.3" /> <TextView android:id="@ + id/tv_data" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="xxxx/xx/xx" android:textSize="20sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.566" app:layout_constraintStart_toEndOf="@ + id/tv_week" app:layout_constraintTop_toBottomOf="@ + id/tv_time_hmin" app:layout_constraintVertical_bias="0.017" /> <TextView android:id="@ + id/tv_time_second" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/ds_digi" android:text="00" android:textSize="48sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.13" app:layout_constraintStart_toEndOf="@ + id/tv_time_hmin" app:layout_constraintTop_toBottomOf="@ + id/tv_AMorPM" app:layout_constraintVertical_bias="0.018" /> <TextView android:id="@ + id/tv_timezone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="92dp" android:text="Beijing time" android:textSize="20sp" app:layout_constraintBottom_toTopOf="@ + id/tv_time_hmin" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" /> </androidx.constraintlayout.widget.ConstraintLayout>
5. Activity
? File name: MyDigitalClockActivity.java
⑴ Private member variables
private ConstraintLayout clClock; // layout private TextView mTimezoneTv; // time zone name private TextView mHminTv, mSecondTv; // time text private TextView mAMorPMTv; // morning and afternoon text private TextView mWeekTv; // week number text private TextView mDataTv; // date text private Timer mTimer; // Timer object private TimeZone mTimeZone; // set the time zone private Calendar mCalendar; // calendar class object private ActionBar actionBar; // ActionBar object
⑵ Custom initialization function
? API
/* * Initialize class members that are initialized only once */ public void init() {<!-- --> clClock = (ConstraintLayout) findViewById(R.id.cl_wzy_digitalclock); mTimezoneTv = (TextView) findViewById(R.id.tv_timezone); mHminTv = (TextView) findViewById(R.id.tv_time_hmin); mSecondTv = (TextView) findViewById(R.id.tv_time_second); mAMorPMTv = (TextView) findViewById(R.id.tv_AMorPM); mWeekTv = (TextView) findViewById(R.id.tv_week); mDataTv = (TextView) findViewById(R.id.tv_data); mTimer = new Timer(); mTimeZone = TimeZone.getTimeZone("GMT + 8:00"); // Beijing time actionBar = getSupportActionBar(); // get ActionBar } // end init
⑶ Navigation bar module
? API
/* * Custom navigation bar style */ public void setActionBar() {<!-- --> actionBar.setTitle("MyDigitalClock--WZY"); // set the title actionBar.setDisplayShowHomeEnabled(true); actionBar.setLogo(R.drawable.clock); // set LOGO actionBar.setDisplayUseLogoEnabled(true); } // end setActionBar
Note: I changed the navigation bar effect of the original title to achieve the expected effect.
⑷Background module
? During daytime: background color is white and all font colors are black ;
? At night, the background color is black and all font colors are white .
Note: This is a small function added by myself (see 6. Final effect for details).
? API
API | Description |
---|---|
setAllTextViewColor |
Modify the font color of all TextView at one time |
changeLayoutColor |
Change the background color and font color according to the current hour |
/* * Modify the font color of all TextViews at once * * @Param color font color */ public void setAllTextViewColor(int color) {<!-- --> // save all TextViews in an array TextView[] textViews = new TextView[]{<!-- -->mTimezoneTv, mHminTv, mSecondTv, mAMorPMTv, mWeekTv, mDataTv}; /* Loop through the array and set the font color one by one */ for (TextView textView : textViews) {<!-- --> textView.setTextColor(color); } } // end setAllTextViewColor /* * Change the background color and font color according to the current hour * * @Param hour current hour */ public void changeLayoutColor(int hour) {<!-- --> if (hour >= 6 & amp; & amp; hour < 18) {<!-- --> /* If it is daytime, set the background color to white and the font color to black */ clClock.setBackgroundColor(Color.WHITE); setAllTextViewColor(Color. BLACK); } else {<!-- --> /* If it is night, set the background color to black and the font color to white */ clClock.setBackgroundColor(Color.BLACK); setAllTextViewColor(Color. WHITE); } } // end changeLayoutColor
⑸ Clock module
? API
API | Description |
---|---|
getCurrentHminTime |
Get the hour and minute of the current time |
getCurrentSecondTime |
Get the seconds of the current time |
getCurrentAMorPM |
Display whether the current time is morning or afternoon |
getCurrentWeek |
Get week number |
getCurrentData |
get date |
updateClockTask |
useTimerTask Update clock |
onDestroy |
Close timing |
/* * Get the hour and minute of the current time */ public String getCurrentHminTime() {<!-- --> int hour = mCalendar.get(Calendar.HOUR_OF_DAY); // HOUR_OF_DAY: 24-hour format int min = mCalendar. get(Calendar. MINUTE); changeLayoutColor(hour); // Change page background and font color return String. format(Locale. CHINA, " d: d", hour, min); } // end getCurrentHminTime /* * Get the current time in seconds */ public String getCurrentSecondTime() {<!-- --> int second = mCalendar. get(Calendar. SECOND); return String. format(Locale. CHINA, "d", second); } // end getCurrentSecondTime /* * Display whether the current time is am or pm */ public String getCurrentAMorPM() {<!-- --> if (mCalendar.get(Calendar.AM_PM) == Calendar.AM) {<!-- --> return "AM"; // AM } else {<!-- --> return "PM"; // afternoon } } // end getCurrentAMorPM /* * Get week number */ public String getCurrentWeek() {<!-- --> String[] weeks = {<!-- -->"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; int week = mCalendar.get(Calendar.DAY_OF_WEEK) - 1; return weeks[week]; } // end getCurrentWeek /* * Acquisition date */ public String getCurrentData() {<!-- --> int year = mCalendar. get(Calendar. YEAR); int month = mCalendar.get(Calendar.MONTH) + 1; // Calendar.MONTH: 0~11 int day = mCalendar. get(Calendar. DAY_OF_MONTH); return String.format(Locale.CHINA, "%d/%d/%d", year, month, day); } // end getCurrentData /* * Use TimerTask to update the clock */ public void updateClockTask() {<!-- --> TimerTask timerTask = new TimerTask() {<!-- --> @Override public void run() {<!-- --> runOnUiThread(() -> {<!-- --> /* Update Calendar and TextView */ mCalendar = Calendar. getInstance(mTimeZone); mHminTv.setText(getCurrentHminTime()); mSecondTv.setText(getCurrentSecondTime()); mAMorPMTv.setText(getCurrentAMorPM()); mWeekTv.setText(getCurrentWeek()); mDataTv.setText(getCurrentData()); }); // end runOnUiThread } // end run }; // end new TimerTask() mTimer.schedule(timerTask, 0, 1000); // update the clock every second } // end updateClockTask /* * Turn off the timer to prevent memory leaks */ protected void onDestroy() {<!-- --> super. onDestroy(); mTimer. cancel(); mTimer = null; } // end onDestroy
⑹onCreate
? API
@Override protected void onCreate(Bundle savedInstanceState) {<!-- --> super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_digital_clock); init(); // initialization setActionBar(); // custom navigation bar style updateClockTask(); // update the clock } // end onCreate
6. Final effect
7. Summary
⑴ String. format() Warning
String. format("d: d", hour, min);
? If String.format()
is written as above, there will be a warning as follows:
Implicitly using the default locale is a common source of bugs: Use `String. format(Locale, ...)` instead
Meaning: Implicit use of the default locale is a common source of error: use ‘ String.format(Locale, …).
The locale of China (
Locale.CHINA
) should be used.-> [reference blog]: http://t.csdn.cn/Oy0BE
? Solution:
String.format(Locale.CHINA, "d: d", hour, min);
⑵Android code naming convention
? Many people tend to ignore the Android code naming convention, resulting in code readability & amp; very poor maintainability, ultimately leading to development efficiency & amp ; Reduced maintenance efficiency.
? Therefore, I deliberately learned the naming convention of Android code and applied it to this assignment (the above code is visible).
-> [reference blog]: https://cloud.tencent.com/developer/article/1408620