Timer + TimerTask 实现数字时钟

354 阅读3分钟

任务:Timer + TimerTask 实现数字时钟

Y)DT(7_XGXLONS~$YFK`UVV.png

完成情况: (后期对其进行了优化,可直达优化后的代码,前面的代码过于重复,可选择性不看)

{(@OGF`Z88QS`SC]JEV3RBR.png

遇到的问题:

1.Android Studio 中 calendar设置系统时区无效的问题

YJ{Z1~D_GG}~4BG9YCGZO$G.png

android里用Calendar取得的时间和手机显示的时间为何不一致?

android中,Calendar会默认使用格林威治时间,Date 及 java.text.SimpleDateFormat都会以与语言环境有关的方法来格式化和解析日期。

之前找了很多种方法都是IntelliJ IDEA 能用,而Android Studio不能用。

Android Studio 中 calendar设置时区无效的问题,改成下面这种形式便可解决。

在Android 8.0以前

TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
Calendar calendar = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = formatter.format(calendar.getTime());
Log.d("testTime",time);

Android 8.0以后设置时区,有所改动,不能直接设置 比如GMT+8:00这样的时区了,要设置 时区的id。

//设置系统时区
TimeZone.setDefault(TimeZone.getTimeZone(timezone));
Calendar cal=Calendar.getInstance();//能获取当前的时间

timezone 要设置为 比如 北京时间 为:Asia/Shanghai 这就是北京时间的时区id。

设置为北京时间的格式显示:

//设置系统时区
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));

2.怎么更改数字字体

原: V)FB%DYIH{}QXS3}58B_[%G.png 现在: {(@OGF`Z88QS`SC]JEV3RBR.png

操作:

打开res,新建一个new Resource Directory,更改Resource type为font.然后导入字体进这个文件夹。 _0R~91HNZ0MWK)UW0Y56SZU.png

命名这个字体为font,如图。然后在layout文件夹里对所需要改变的文本增加一行代码:

android:fontFamily="@font/font"

9$Y7B714H}32%XF`K9PY1.png

核心代码

ActionBar:

8_D`QAUO@WKM}UN(W[P{D_L.png
ActionBar actionBar = getSupportActionBar(); //获取ActionBar
        actionBar.setTitle("TimerDemo01"); //设置标题

part1:显示HH:mm

public static String getDate1(){
        Calendar cal=Calendar.getInstance();//能获取当前的时间
        //设置系统时区
        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
        /*SimpleDateFormat:
        一个与语言环境相关的格式化日期和分析日期的工具类。
         *利用该类可以将日期转换成文本,或者将文本转换成日期*/
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        return sdf.format(cal.getTime());
    }

part2:AM/PM

public static String getDate2(){
        Calendar cal = Calendar.getInstance();
        Integer dateValue = Integer.valueOf(String.valueOf(cal.getTime()).substring(11,13));//得到小时
        return dateValue>=12?"PM":"AM";
    }

part3: 显示秒

public static String getDate3(){
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("ss");
        return sdf.format(cal.getTime());
    }

part4:显示星期

public static String getDate4(){
        String[] weeks = {"周日","周一","周二","周三","周四","周五","周六"};
        Calendar cal = Calendar.getInstance();
        /*获取当前的星期 星期返回0-6;
        分别代表   星期日--星期六(故-1)*/
        int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
        return weeks[week_index];
    }

part5:显示年/月/日

public static String getDate5(){
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        return sdf.format(cal.getTime());
    }

总代码:TimerDemoActivity01

package com.example.helloandroid2;
 
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
 
import android.os.Bundle;
import android.widget.TextView;
 
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
 
public class TimerDemoActivity01 extends AppCompatActivity {
 
    private Timer timer;
    private TimerTask task;
    private TextView tv1,tv2,tv3,tv4,tv5;
    public static String getDate1(){
        Calendar cal=Calendar.getInstance();//能获取当前的时间
        //设置系统时区
        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
        /*SimpleDateFormat:
        一个与语言环境相关的格式化日期和分析日期的工具类。
         *利用该类可以将日期转换成文本,或者将文本转换成日期*/
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        return sdf.format(cal.getTime());
    }
    public static String getDate2(){
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("HH");
        Integer dateValue = Integer.valueOf(String.valueOf(cal.getTime()).substring(11,13));//得到小时
        return dateValue>=12?"PM":"AM";
    }
    public static String getDate3(){
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("ss");
        return sdf.format(cal.getTime());
    }
    public static String getDate4(){
        String[] weeks = {"周日","周一","周二","周三","周四","周五","周六"};
        Calendar cal = Calendar.getInstance();
        /*获取当前的星期 星期返回0-6;
        分别代表   星期日--星期六(故-1)*/
        int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if(week_index<0){
            week_index = 0;
        }
        return weeks[week_index];
    }
    public static String getDate5(){
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        return sdf.format(cal.getTime());
    }
 
    public void init() {
        timer = new Timer();
 
        tv1 = (TextView) findViewById(R.id.textView1);
        tv2 = (TextView) findViewById(R.id.textView2);
        tv3 = (TextView) findViewById(R.id.textView3);
        tv4 = (TextView) findViewById(R.id.textView4);
        tv5 = (TextView) findViewById(R.id.textView5);
        task = new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() { //在定时任务线程中再启动一个runOnUiThread 线程去更新UI
                    @Override
                    public void run() {
                        tv1.setText(getDate1());
                        tv2.setText(getDate2());
                        tv3.setText(getDate3());
                        tv4.setText(getDate4());
                        tv5.setText(getDate5());
                    }
 
                });//end runOnUiThread
            }
        };
    }
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_timer_demo01);
 
        init();
 
        timer.schedule(task,0,1000);
 
        ActionBar actionBar = getSupportActionBar(); //获取ActionBar
        actionBar.setTitle("TimerDemo01"); //设置标题
    }
}

layout文件:activity_timer_domo01.xml

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    tools:context=".TimerDemoActivity01">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/font"
        android:text="20:19"
        android:textColor="@color/white"
        android:textSize="96sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.352"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.409" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="PM"
        android:textColor="@color/white"
        android:textSize="24sp"
        app:layout_constraintBottom_toTopOf="@+id/textView3"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.192"
        app:layout_constraintStart_toEndOf="@+id/textView1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.973" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/font"
        android:text="49"
        android:textColor="@color/white"
        android:textSize="48sp"
        app:layout_constraintBaseline_toBaselineOf="@+id/textView1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.106"
        app:layout_constraintStart_toEndOf="@+id/textView1" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="100dp"
        android:text="周五"
        android:textColor="@color/white"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView1"
        app:layout_constraintVertical_bias="0.0" />

    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="2023/3/7"
        android:textColor="@color/white"
        android:textSize="24sp"
        app:layout_constraintBaseline_toBaselineOf="@+id/textView4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.46"
        app:layout_constraintStart_toEndOf="@+id/textView4" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="-1dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

优化后代码: TimerDemoActivity01

package com.example.helloandroid2;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;

public class TimerDemoActivity01 extends AppCompatActivity {

    private Timer timer;
    private TimerTask task;
    private TextView tv1,tv2,tv3,tv4,tv5;
    Calendar cal;

    public void init() {
        timer = new Timer();
        String[] weeks = {"周日","周一","周二","周三","周四","周五","周六"};

        tv1 = (TextView) findViewById(R.id.textView1);
        tv2 = (TextView) findViewById(R.id.textView2);
        tv3 = (TextView) findViewById(R.id.textView3);
        tv4 = (TextView) findViewById(R.id.textView4);
        tv5 = (TextView) findViewById(R.id.textView5);

        //设置系统时区
        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));

        task = new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() { //在定时任务线程中再启动一个runOnUiThread 线程去更新UI
                    @Override
                    public void run() {
                        cal = Calendar.getInstance();//能获取当前的时间,一定要换在TimerTask()里面,这样每回才会刷新
                        tv1.setText(
                                String.format("%02d:%02d",cal.get(Calendar.HOUR_OF_DAY),cal.get(Calendar.MINUTE))
                        );
                        tv2.setText(
                                //判断当前时间是上午还是下午----0为上午,1为下午
                                cal.get(Calendar.AM_PM)==0?"AM":"PM"
                        );
                        tv3.setText(
                                String.format("%02d",cal.get(Calendar.SECOND))
                        );
                        tv4.setText(
                                //获取对应日期是该周的第几天
                                weeks[cal.get(Calendar.DAY_OF_WEEK) - 1]
                        );
                        tv5.setText(
                                //获取对应日期的月份,月份从0开始,故为cal.get(Calendar.MONTH)+1
                                String.format("%4d/%d/%d",cal.get(Calendar.YEAR),cal.get(Calendar.MONTH)+1,cal.get(Calendar.DATE))
                        );
                    }

                });//end runOnUiThread
            }
        };
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_timer_demo01);

        init();

        timer.schedule(task,0,1000);

        ActionBar actionBar = getSupportActionBar(); //获取ActionBar
        actionBar.setTitle("TimerDemo01"); //设置标题
    }
}