时间轮盘app实现
在mac上看到一款炫酷锁屏,所以按照自己的思路实现了其中一个效果,顺手码了个App,名为“时间轮盘”。“时间轮盘”包括动态壁纸和屏保功能。
下载地址
实现效果

准备
工欲善其事必先利其器,要实现功能首先需要了解相关技术栈。“时间轮盘”涉及到绘制,因此需要了解Canvas,Paint,Matrix相关Api。最终需要将绘制的图形展示到动态壁纸和屏保,因此需要分别继承WallpaperService和DreamService,并实现相关方法。
实现
1.绘制轮盘
实现程序绕不开绘制,因此我们先自定义一个View,重写onDraw()方法来实现轮盘的绘制。根据效果图分析,轮盘的环绕文字从内向外逐层显示,每一层显示一种具体时间字段。所以我们先实现一层(月份)绘制,接下的按照同样的方法进行绘制。
查阅文档,安卓关于文字绘制有以下方法
1 | public void drawText (CharSequence text, int start, int end, float x,float y, Paint paint) |
我们只需要使用到
1 | public void drawText (String text, float x, float y, Paint paint) |
首先我们现在原点进行绘制”一月”,那么我们如何将绘制内容移动到画布中央呢,这时候我们就需要用到Matrix,Matrix在图形绘制中起着重要的作用,通过Matrix我们可以实现图形的缩放,旋转,平移以及它们的组合效果。
先使用
1 | public boolean postTranslate(float dx, float dy) |
进行平移,根据效果图我们发现绘制距离中点还有一定距离,我们仅需再向右平移一段距离,最后通过调用
1 | Canvas.setMatrix(Matrix matrix) |
来应用Matrix,就可以愉快的绘制了。
接下来我们再绘制”二月”,和”一月”不同的是,”二月”相对于”一月”有一定的偏转角度,我们只要围绕画布中心点进行旋转就行了。
1 | public boolean postRotate(float degrees, float px, float py) |
旋转角度为360/12=30,同理接下来的月份就好办了。
将代码封装下
1 | private String[] months = { |
通过以上代码,我们便能够实现一个静态的时间轮盘了。
2.显示正确的时间
根据效果图我们知道,当前时间高亮显示,并且总是显示在右侧一行。我们需要将整个圆环进行旋转,一直转到当前时间。
首先我们通过调用Calendar的方法
1 | public int get(int field) |
获取到月,日等时间字段,拿月示例,现在是四月,根据
1 | Calendar.get(Calendar.MONTH) |
我们获取到的值3,我们只需要逆时针旋转(360/12)*3就能够将四月旋转到正确的位置,并且将其设置高亮色,其他同理。
3.让我们的轮盘动起来
通过 (当前毫秒%1000/1000f) * 360 可以知道当前秒数的偏移量,在绘制的时候只要再加上这个偏移量,再通过一个定时器定时的执行重绘工作,便可以实现轮盘的转动了。
4.显示到壁纸
4.1添加壁纸权限
1 | <uses-permission android:name="android.permission.SET_WALLPAPER"/> |
4.2实现壁纸服务
继承WallpaperService并实现onCreateEngine1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32override fun onCreateEngine(): WallpaperService.Engine {
return LiveWallpaperEngine()
}
private inner class LiveWallpaperEngine : WallpaperService.Engine() {
override fun onSurfaceCreated(holder: SurfaceHolder) {
super.onSurfaceCreated(holder)
//获取画布
val canvas = holder!!.lockCanvas()
//绘制到画布
...
...
//显示到屏幕
holder!!.unlockCanvasAndPost(canvas)
}
override fun onVisibilityChanged(visible: Boolean) {
super.onVisibilityChanged(visible)
//为了省电,我们可以在壁纸不显示的时候,停止绘制线程
}
override fun onSurfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
super.onSurfaceChanged(holder, format, width, height)
//在屏幕旋转时调整画布大小
}
override fun onSurfaceDestroyed(holder: SurfaceHolder) {
super.onSurfaceDestroyed(holder)
//销毁绘制线程
}
}
4.3添加my_wallpaper.xml
1 |
|
4.4添加服务到清单
1 | <service |
4.5跳转设置壁纸
1 | Intent intent = new Intent(); |
网页版轮盘
https://ghbhaha.github.io/DateTimewallpaper_Communication/editer.html
原文作者: ghbhaha
原文链接: /2019/04/09/时间轮盘app实现/
版权声明: 转载请注明出处(必须保留作者署名及链接)