小项目开发——Timer + TimerTask 实现数字时钟
目录
文章目录
- 目录
- 小项目开发——Timer + TimerTask 实现数字时钟
- 1. 题目
- 2. 结构分析
- 3. 模块思维导图
- 4. Layout
- ⑴ 视图
- ⑵ 导航栏 LOGO
- ⑶ Android 七段数码管字体
- ⑷ 代码
- 5. Activity
- ⑴ 私有成员变量
- ⑵ 自定义初始化函数
- ⑶ 导航栏模块
- ⑷ 背景模块
- ⑸ 时钟模块
- ⑹ onCreate
- 6. 最终效果
小项目开发——Timer + TimerTask 实现数字时钟
1. 题目
◼Timer
+TimerTask
实现数字时钟.
◼ 期望最终效果:
2. 结构分析
◼ 主要分为 3 个大模块:导航栏、背景、时钟.
◼ 当然,与这 3 大模块相关的小模块也有许多.
3. 模块思维导图
4. Layout
◼ Android 开发首先应设计好页面布局(activity_my_digital_clock.xml).
◼ 布局id
:cl_wzy_digitalclock
.
⑴ 视图
◼ 主要是 时钟模块 的6个TextView
:
⑵ 导航栏 LOGO
◼ 在这个网站上寻找到了时钟 LOGO 资源: Search results for Clock - Flaticon.
◼ 并将图片资源 icon_clock.png 导入到了 res/drawable 中.
◼ 同时编写了相应的 clock.xml 文件,将其修改为白色以适配导航栏的背景色.
<?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 七段数码管字体
◼ 在这个网站上寻找到了字体资源: DS-Digital Font | dafont.com.
◼ 并将字体资源 ds_digi.TTF 导入到了 res/font 文件夹中.
◼ 然后在 xml 文件的组件中以如下方式使用该字体.
android:fontFamily="@font/ds_digi"
⑷ 代码
<?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="北京时间"
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
◼ 文件名:MyDigitalClockActivity.java
⑴ 私有成员变量
private ConstraintLayout clClock; // 布局
private TextView mTimezoneTv; // 时区名
private TextView mHminTv, mSecondTv; // 时间文本
private TextView mAMorPMTv; // 上下午文本
private TextView mWeekTv; // 周数文本
private TextView mDataTv; // 日期文本
private Timer mTimer; // Timer 对象
private TimeZone mTimeZone; // 设置时区
private Calendar mCalendar; // 日历类对象
private ActionBar actionBar; // ActionBar 对象
⑵ 自定义初始化函数
◼ API
/*
* 对只用初始化一次的类成员初始化
*/
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"); // 北京时间
actionBar = getSupportActionBar(); // 获取 ActionBar
} // end init
⑶ 导航栏模块
◼ API
/*
* 自定义导航栏样式
*/
public void setActionBar() {
actionBar.setTitle(" MyDigitalClock——WZY"); // 设置标题
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setLogo(R.drawable.clock); // 设置 LOGO
actionBar.setDisplayUseLogoEnabled(true);
} // end setActionBar
注:改了一下原题目预期实现效果的导航栏效果.
⑷ 背景模块
◼ 在 白天 时:背景颜色 为 白色,所有 字体颜色 为 黑色;
◼ 在 夜晚 时,背景颜色 为 黑色,所有 字体颜色 为 白色.
注:这是我自己加的一个小功能(详见6. 最终效果).
◼ API
API | 说明 |
---|---|
setAllTextViewColor | 一次性修改所有TextView 的字体颜色 |
changeLayoutColor | 根据当前小时数改变背景颜色和字体颜色 |
/*
* 一次性修改所有 TextView 的字体颜色
*
* @Param color 字体颜色
*/
public void setAllTextViewColor(int color) {
// 将所有的 TextView 保存在数组中
TextView[] textViews = new TextView[]{mTimezoneTv, mHminTv, mSecondTv, mAMorPMTv, mWeekTv, mDataTv};
/* 循环遍历数组,依次设置字体颜色 */
for (TextView textView : textViews) {
textView.setTextColor(color);
}
} // end setAllTextViewColor
/*
* 根据当前小时数改变背景颜色和字体颜色
*
* @Param hour 当前小时数
*/
public void changeLayoutColor(int hour) {
if (hour >= 6 && hour < 18) {
/* 如果是白天,设置背景颜色为白色,字体颜色为黑色 */
clClock.setBackgroundColor(Color.WHITE);
setAllTextViewColor(Color.BLACK);
} else {
/* 如果是夜晚,设置背景颜色为黑色,字体颜色为白色 */
clClock.setBackgroundColor(Color.BLACK);
setAllTextViewColor(Color.WHITE);
}
} // end changeLayoutColor
⑸ 时钟模块
◼ API
API | 说明 |
---|---|
getCurrentHminTime | 获取当前时间的小时和分钟数 |
getCurrentSecondTime | 获取当前时间的秒数 |
getCurrentAMorPM | 显示当前时间是上午还是下午 |
getCurrentWeek | 获取周数 |
getCurrentData | 获取日期 |
updateClockTask | 使用TimerTask 更新时钟 |
onDestroy | 关闭定时器,防止内存泄露 |
/*
* 获取当前时间的小时和分钟数
*/
public String getCurrentHminTime() {
int hour = mCalendar.get(Calendar.HOUR_OF_DAY); // HOUR_OF_DAY:24小时制
int min = mCalendar.get(Calendar.MINUTE);
changeLayoutColor(hour); // 改变页面背景和字体颜色
return String.format(Locale.CHINA, "%02d:%02d", hour, min);
} // end getCurrentHminTime
/*
* 获取当前时间的秒数
*/
public String getCurrentSecondTime() {
int second = mCalendar.get(Calendar.SECOND);
return String.format(Locale.CHINA, "%02d", second);
} // end getCurrentSecondTime
/*
* 显示当前时间是上午还是下午
*/
public String getCurrentAMorPM() {
if (mCalendar.get(Calendar.AM_PM) == Calendar.AM) {
return "AM"; // 上午
} else {
return "PM"; // 下午
}
} // end getCurrentAMorPM
/*
* 获取周数
*/
public String getCurrentWeek() {
String[] weeks = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
int week = mCalendar.get(Calendar.DAY_OF_WEEK) - 1;
return weeks[week];
} // end getCurrentWeek
/*
* 获取日期
*/
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
/*
* 使用 TimerTask 更新时钟
*/
public void updateClockTask() {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
runOnUiThread(() -> {
/* 更新 Calendar 和 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); // 每秒更新一次时钟
} // end updateClockTask
/*
* 关闭定时器,防止内存泄露
*/
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(); // 初始化
setActionBar(); // 自定义导航栏样式
updateClockTask(); // 更新时钟
} // end onCreate
Re.Gin: 环境这东西是这样的
Re.Gin: 这个得去找一下开源工具,目前我还不了解有哪些
吴继薇: 请问如何手动选择点 来生成mask
jadeyee: 搞出来了,,什么都没变用vs code运行就没问题了,pycharm还是不行
jadeyee: 您好,改过了版本还是显示找不到文件,然后降了cuda版本,官方113我降到了111,按照您的方法运行了,那几个文件都安装成功了,结果运行text的时候报错了name _c,请问您的cuda和配套的torch版本是什么