Timer + TimerTask implements digital clock

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