利用C#语言实现跨平台小闹钟


本文由 CDFMLR 原创,收录于个人主页 https://clownote.github.io,并同时发布到 CSDN。本人不保证 CSDN 排版正确,敬请访问 clownote 以获得良好的阅读体验。


利用 C# 语言实现跨平台小闹钟

前言

学校的课程要求做一个 C# 小闹钟程序设计,具体要求如下:

  1. 做一个小闹钟窗体应用程序。
  2. 具备实时显示数字时钟的功能,方便使用者获取当前的时间。
  3. 具备实时绘制表盘时钟的功能,根据当前时间再来绘制秒针、分针和时针。
  4. 具备整点报时的功能,当处于整点时,系统进行报时。
  5. 具备定点报时的功能,根据使用者的设定,进行报时。
  6. 把使用者设置的报时时间,记录在文本文件中,系统在启动时,自动加载该文本文件以便获取定点报时的时间。
  7. 系统最小化时,缩小为系统托盘。

这个东西不难,就是最简单的 App 开发嘛,但要求用 C# 做 Windows 窗体就很烦。由于我不使用 Windows 系统,所以拿到题目,首先的想法就是跨平台,我希望在 Mac 上完成开发,然后直接打包发布到 Windows 平台。

以前看过好几个跨平台的开源的 UI 实现项目都是 C# 写的,比如 Pathos: Nethack Codex 用的 Invention。但因为我之前甚至从没用过 C#,所以对于它们具体的实现不是很了解。经过一阵 Google,我找到了 Microsoft 自家做的跨平台方案——Xamarin。

emmmm,Xamarin 还分好几个部分,Xamarin.Forms,Xamarin.Mac 什么的。其中,Xamarin.Forms 可以一套 UI 代码生成 Android、iOS、UWP(支持不完整,还是预览版)。这个框架下 Android、iOS 可以在 Mac 上用 Visual Studio for Mac 来开发并且生成,UWP 只能在 Windows 下生成。

这个东西感觉还不错,看文档里生成出来的 UI 效果挺好看的,代码也比较简单(相较于原生 Android 开发),所以我决定用这个 Xamarin.Forms 先在 Mac 下完成这个小闹钟的开发,然后借一台 Windows 电脑来生成 UWP。

决定了框架,然后就是 C# 基础语法和 Xamarin.Forms 的学习了。这两个东西微软都有详细的、针对各种不同技术水平的开发者的入门教程,顺着看一遍,把例子写一下也就足够完成这次的小闹钟任务了。

接下来就进入跨平台小闹钟开发的过程了。

设计

我们首先思考我们期望的 App 使用场景:用户点击打开 App,屏幕上显示出一个圆盘时钟,然后,可以从导航条(iOS 的习惯是底部,Android 和 UWP 为顶部)切换到一个现实这闹钟条目到界面,用户可以在这里点开一条闹钟条目进行编辑,或着添加新的闹钟条目。

iOS 自带的 “时钟” App 给了我们很好的参考(由于它没有圆盘时钟功能,我截了一张“就寝”界面替代😓):

IMG_1573

在我们的设计中,小闹钟 App 可以分为这样几个页面:

  • 🕤时钟页:显示一个圆盘时钟,展示当前时间;
  • ⏰闹钟页:显示当前设定的所有闹钟条目,可以点开编辑、新建闹钟条目;
  • 🧾详情页:新建、编辑一条闹钟的时间、注释的页面,并有保存、删除的功能。

具体到 Xamarin.Forms 中,这些 Pages 如下图所示:

MyClockPagesDiagram

然后,我们还需要设计另外一个重要的部分,一条“闹钟”的表示和储存。

可以考虑用一个 AlarmItem 类来代表一条闹钟,这个类要具有 唯一ID、时间、是否打开、注释 这几个属性。

在 Xamarin 中,我们可以很方便地引入 SQLite 储存这个对象,只需要写一个 Database 类,简单封装一下 CRUD,方便后续使用。

接下来就要开始代码实现了,先贴出最后成品截图,iOS上的效果:

IMG_1576

UWP 的效果:

IMG_1600

实现

整个 App 的基础大概有了,现在考虑一些实现的细节。

(在这里我只列出关键的或者任何我认为有意思的代码片段,完整代码见 GitHub

圆盘时钟的实现

屏幕快照 2019-12-09 13.36.51

绘制一个如上图所示的圆盘时钟,需要实时的矢量图绘制。Xamarin.Forms 不具有内置的矢量图形系统,但有一个 BoxView 可帮助进行补偿。BoxView 呈现指定的宽度、 高度和颜色的一个简单的矩形。参照微软的文档,我们可以按下面的思路实现一个时钟:

表盘

对于表盘,通过简单的数学计算,就可以得到从12点开始的表盘上 60 个均匀分布的刻度点的位置坐标。在一个可以指定位置的 AbsoluteLayout 中。

// Create the tick marks
for (int i = 0; i < tickMarks.Length; i++)
{
	tickMarks[i] = new BoxView { Color = Color.Black };
	absoluteLayout.Children.Add(tickMarks[i]);
}

上面我们生成了 60 个大小相同的正方形 BoxView,现将模5的点稍微加大,然后把它们放置到指定的位置,针对不同位置的正方形做一个使其正对中心的旋转,表盘就完成了。

// Size and position a tickMark
double size = radius / (index % 5 == 0 ? 15 : 30);
double radians = index * 2 * Math.PI / tickMarks.Length;
double x = center.X + radius * Math.Sin(radians) - size / 2;
double y = center.Y - radius * Math.Cos(radians) - size / 2;
AbsoluteLayout.SetLayoutBounds(tickMarks[index], new Rectangle(x, y, size, size));
tickMarks[index].Rotation = 180 * radians / Math.PI;
指针

接下来是指针,先在之前的 AbsoluteLayout 中实例化三个代表时分秒针的 BoxView:

<AbsoluteLayout x:Name="absoluteLayout" SizeChanged="OnAbsoluteLayoutSizeChanged">
    <BoxView x:Name="hourHand" Color="Black" />
    <BoxView x:Name="minuteHand" Color="Black" />
    
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值