Garmin MonkeyC的写法和经验

避免

  • 通过eclipse可以方便创建garmin项目, 但是要注意一点, app/face/widget/data模板都不一样, 中途切换会导致程序错误或者api权限不够, 想创建什么类型APP提前选择好类型
  • 背景色不要设置成复杂的贴图纹理, 这样叠加图层时将渲染成非透明不混合方式以优化手表性能和耗电量

分类

当你用中文手表app的时候, 会列出来这几项, 下面进行一一对应和说明
(按键以forrunner235为例)

中文名 英文名 按键 权限
应用程序 application / app 所有按键 权限完全开通, 无任何限制, 制作码表记录轨迹等需要长时间开启的应用, 在这里创建表盘会十分耗电切记
小工具 widget 确定/菜单/多层时支持返回/上/下 在手表默认表盘上下切换的临时应用/小工具, 它不支持动画, 大概30/60秒就自动回到默认表盘, 适合堆放临时信息, 比如心率/天气运动量统计/电量显示等
屏幕背景 watchface 默认界面, 表盘在初始化/甩手腕/从其他应用返回时提供秒钟刷新, 几秒后进入省电模式, 变为分钟刷新, 所以这里不适合做动画效果
数据字段 data field 为佳明运动app栏位显示, 佳明运动app支持将屏幕分割出多个区域, 数据位会显示在指定区域中, 功能和应用程序一样, 只是区域和按键有区别

代码相关

  • 获取手表时间
var time = Sys.getClockTime();
time.sec time.min time.hour

用户设置的时间格式12/24

Gfx.System.getDeviceSettings().is24Hour

根据用户设置显示小时

var hourAuto = (!Gfx.System.getDeviceSettings().is24Hour&&time.hour>12)?time.hour%12:time.hour;
hourAuto.format("%02d")
  • 获取日期
//Time.FORMAT_MEDIUM 为文字描述的长度
var date = Gregorian.info(Time.now(), Time.FORMAT_MEDIUM);
var timeString = Lang.format("$1$-$2$  $3$", [date.month,date.day,date.day_of_week]);
  • 系统屏幕类型
var isShapeRect = Sys.getDeviceSettings().screenShape == Sys.SCREEN_SHAPE_RECTANGLE;
  • 系统颜色
    COLOR_WHITE 白
    COLOR_LT_GRAY 亮灰
    COLOR_DK_GRAY 暗灰
    COLOR_BLACK 黑
    COLOR_RED 亮红
    COLOR_DK_RED 暗红
    COLOR_ORANGE 橙色/暗黄
    COLOR_YELLOW 亮黄
    COLOR_GREEN 亮绿
    COLOR_DK_GREEN 暗绿
    COLOR_BLUE 亮蓝
    COLOR_DK_BLUE 暗蓝
    COLOR_PINK 粉/亮紫
    COLOR_PURPLE 暗紫
    COLOR_TRANSPARENT 透明(尽量少用)
  • 系统字体
    只有相对大小的5种, 对应每块手表的相对大小, 如果你需要更大的字体, 则需要借助fnt扩展, 或者使用位图资源
    1.0.x支持字体
    FONT_XTINY 最小&纤细
    FONT_TINY 最小号
    FONT_SMALL 小号
    FONT_MEDIUM 中号
    FONT_LARGE 大号
    FONT_NUMBER_MILD (只用于数字)
    FONT_NUMBER_MEDIUM (只用于数字)
    FONT_NUMBER_HOT (只用于数字)
    FONT_NUMBER_THAI_HOT (只用于数字)
    1.3.x支持字体
    FONT_SYSTEM_XTINY 系统最小&纤细
    FONT_SYSTEM_TINY 系统最小号
    FONT_SYSTEM_SMALL 系统小号
    FONT_SYSTEM_MEDIUM 系统中号
    FONT_SYSTEM_LARGE 系统大号
    FONT_SYSTEM_NUMBER_MILD 系统大号+(只用于数字)
    FONT_SYSTEM_NUMBER_MEDIUM 系统大号++ (只用于数字)
    FONT_SYSTEM_NUMBER_HOT 系统大号+++(只用于数字)
    FONT_SYSTEM_NUMBER_THAI_HOT 系统大号++++ (只用于数字)
    https://developer.garmin.com/downloads/connect-iq/monkey-c/doc/Toybox/Graphics.html
  • 使用fnt字体 (fnt制作工具请自行搜索)
    • 先将fnt文件拷贝到resources/drawables里面
    • 然后修改描述文件drawables.xml, 将默认的drawables集合外面包含一层resources
    • 把font加入进去
    • 代码中调用此字体
<resources>
<drawables>
    <bitmap id="LauncherIcon" filename="launcher_icon.png" />
</drawables>
<font id="fntTime1" filename="fntNum1.fnt" antialias="true"/>
</resources>

var fntTime1 = Ui.loadResource(Rez.Fonts.fntTime1);
  • 创建文本
    一共有三种方法,
  1. 默认模板会提供第一种, 也就是在resources/layouts下的xml配置文件里直接配置, 并通过onLayout加载进来
function onLayout(dc) {
        setLayout(Rez.Layouts.WatchFace(dc));
}
  1. 创建有对象控制的文本函数
var txtUnit = new Ui.Text({
                :text=>"",
                :color=>Gfx.COLOR_WHITE,
                :backgroundColor=>Gfx.COLOR_RED,
                :font=>fntTime1,
                :locX=>winW*.5f,
                :locY=>i*winH*.2f,
                :justification=>Gfx.TEXT_JUSTIFY_CENTER
});
//在onUpdate(dc)中绘制
txtUnit.draw(dc);

3.直接在onUpdate(dc)中绘制不带函数控制的渲染

dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
dc.drawText(100, 100 , fntTime1, i*10, Gfx.TEXT_JUSTIFY_CENTER);

不管哪一种都支持用fnt字体或系统内置字体

  • 获取文本大小
    getTextDimensions(text, font)

  • 如何文本居中
    实际上设置 justification=>Gfx.TEXT_JUSTIFY_CENTER 可以令文本横向居中, 也就是locX位置为问题文本中心轴的位置, 而纵向呢, 纵向有两种方法设置居中
    当你设置locY=>winSizeHeight*.5 并不是垂直居中, 你如何得到文本的高度呢, 非常简单

  1. 如果用上面第二种方法创建的文本, 并不能直接对对象进行获取txt.height, 因为没有进行draw(dc)渲染, 需要在onUpdate(dc)中进行了它draw(dc)后获取位置
  2. 第一种方法太麻烦了, 而且刷新时频繁计算又费事费电, 其实很简单, 系统给了api解决这一问题, 不需要渲染对象, 在创建之前就已经知道这个字体的高度了
var ftHHalf = Gfx.getFontHeight(Gfx.FONT_SYSTEM_NUMBER_HOT)*.5f;
  1. 隐藏属性, 发现还有更简单的设置方法....
设置justification为Gfx.TEXT_JUSTIFY_CENTER|Gfx.TEXT_JUSTIFY_VCENTER
  • 如何使用数组
    var pool = [];
    加入对象
    pool.add(obj);
    获取大小
    pool.size();
    遍历
var len = pool.size();
for(var i=0;i<len;i++){
  //do you want
}
  • 如何设置计时器
var timer  = new Timer.Timer();
timer.start(method(:requestUpdate), 10000, true);

停止/销毁计时器

if(timer!=null){
    timer.stop();
    timer = null;
}

计时器只工作在app(任何时候), widget(关闭之前), face (唤醒状态function onExitSleep()调用时) (休眠状态 function onEnterSleep()记得销毁和完成最后一次刷新表盘<比如秒针消除掉>)
face在休眠状态下调用timer会弹出警告, 提示权限不够, 不进行执行

  • 枚举的创建和使用
    MonkeyC既然从c语言简化而来, 自然也支持枚举
    创建
enum{
        TypeMode_Default,
        TypeMode_Animation,
        TypeMode_PowerSave
}

使用

switch(colorTemplete){
        case TypeMode_PowerSave:
                //do sth
            break;
        case TypeMode_Default:
        default:
                break;
}
  • 强制Ui刷新
    Ui.requestUpdate();
    app通过animate或者timer可以达到每秒多次刷新
    watchface可以在唤醒状态使用timer刷新

  • 如何输出, 错误

  1. 输出log
    Sys.println(str);
  2. 弹出错误
    Sys.error(str);
  • 如何使用数学函数Math
    using Toybox.Math;
  1. 获取随机数
function rand(num){
        Math.srand(Math.rand());
        return Math.rand()%num;
}
  1. 获取随机0~1小数
function ran(){
        Math.srand(Math.rand());
        return Math.rand()%10000/10000.0f;
}
  • 绘制图形
    Toybox::Graphics::Dc
  1. clear 用背景色填充屏幕
  2. clearClip 重置dc整个区域 (2.3)
  3. drawArc(x, y, r, attr, degreeStart, degreeEnd) 画弧
  4. drawBitmap(x, y, rez) 将资源贴图绘制上来
  5. drawCircle(x, y, radius) 画圈
  6. drawEllipse(x, y, a, b) 画椭圆圈
  7. drawLine(x1, y1, x2, y2) 画线
  8. drawPoint(x, y) 画点
  9. drawRectangle(x, y, width, height) 画矩形框
  10. drawRoundedRectangle(x, y, width, height, radius) 画圆角矩形框
  11. drawText(x, y, font, text, justification) 绘制文本
  12. fillCircle(x, y, radius) 画圆
  13. fillEllipse(x, y, a, b) 画椭圆
  14. fillPolygon(pts) 画多边形
  15. fillRectangle(x, y, width, height) 画矩形
  16. fillRoundedRectangle(x, y, width, height, radius) 画圆角矩形
  17. setClip(x, y, width, height) 设置dc的绘制区域
  18. setColor(foreground, background) 设置前景色和背景色, 通过创建对象后刷新不会因为setColor而改变, 需要通过自己的函数setColor以及setBackgroundColor进行改变
  19. setPenWidth(width) 设置线宽度
  • view的运行次序
    插件和应用
    onLayout() → onShow() → onUpdate() → onHide()
    表盘
    onLayout() → onShow() → onUpdate()
    数据栏
    onLayout() → onShow() → onUpdate()

这些都是任何语言都具备的功能, 然后下一篇如果经验积累够了会讲手表感应器api(心率,gps等), 或者手表自带组件(个人感觉没太大兴趣)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容