应用

FAQ1 如何新增一个应用(内置、外置)

应用由代码文件资源文件(包含图片、动画、多语言配置文件等)两部分组成。 新增内置/外置应用的完整流程,可参考文档:创建一个新应用


FAQ2 如何基于已有应用修改为自定义应用

1. 修改内置应用

修改内置应用需分别处理代码文件资源文件,具体步骤如下:

1.1 代码修改

  1. 完整复制已有应用的整个目录,将目录名、所有相关文件名统一修改为自定义名称(建议遵循项目命名规范,如小写字母+下划线的命名格式)。 应用代码目录修改示例

  2. 清理冗余文件:删除与自定义应用功能无关的代码文件、配置文件。

  3. 处理函数关联依赖:逐一检查并调整代码中对原有目录、文件名、函数名的引用,确保所有关联逻辑指向修改后的内容,避免出现调用异常。

1.2 资源文件替换与适配

  1. 复制已有应用的资源目录,删除其中不需要的冗余资源(如多余的图片、动画文件)。 资源目录修改示例

  2. 将自定义的新资源按原有目录结构放置到对应位置。

  3. 分辨率适配处理:参照新增应用分辨率支持文档进行适配,同时同步更新软件代码中对该资源名称的引用,确保资源能正常加载。

2. 修改外置应用

外置应用的代码与资源文件存放在同一目录下,修改流程更简化:

  1. 选择一个现有外置应用,复制其整个目录并修改为自定义名称。 外置应用目录修改示例

  2. 其余修改步骤,参照外置应用创建流程执行即可。


FAQ3 如何删除一个已有的应用

1. 删除内置应用

删除内置应用需分代码删除资源删除两个独立步骤,具体操作如下:

1.1. 删除代码

  • 代码存放路径solution/examples/xxx/application/(其中xxx为具体产品型号,如watchgridview等)。

  • 操作方法:直接删除对应应用的整个目录即可。

  • 示例:删除guide应用,可直接删除路径:solution\examples\watch\application\guide删除内置应用代码示例

1.2. 删除资源

  • 内置应用资源存放路径solution/examples/xxx/resource/

  • 操作方法:仅需删除images目录下对应应用的子目录即可;公共资源以及多语言表无需处理(原因:未使用的资源在编译时不会被链接,不影响项目体积;多语言表是从代码中检索生成的,会自动更新)。 删除内置应用资源示例

2. 删除外置应用

2.1. 静态删除(项目编译前)

  • 外置应用存放路径solution/examples/_dynamic_app/application/

  • 应用类型与删除规则:该目录下包含C应用、Python应用、QJS应用、Tool应用等类型的外置应用,动态应用的代码与资源文件均存放在同一目录中。

  • 操作方法:根据要删除的应用类型,进入对应子目录,直接删除整个目录。

  • 示例:删除C应用下的alarm应用,删除路径:solution/examples/_dynamic_app/application/c/app/alarm删除动态应用示例

2.2. 动态删除(程序运行时)

外置应用支持程序运行后动态删除,具体操作参照:删除外置应用

FAQ4 如何添加全局自定义动画

1 新增动画类型

动画类型由主ID和次ID组成,主ID需唯一标识该动画,且不能与现有的重复。动画类型的主ID号划分方式如下: 0 == LV_SWITCHANIM_NONE : 0 ~ LV_SWITCHANIM_CUSTOMER : LV_SWITCHANIM_CUSTOMER : LV_SWITCHANIM_DEFAULT 为系统内置动画使用,(LV_SWITCHANIM_CUSTOMER,LV_SWITCHANIM_CUSTOMER)客户自定义动画可以从LV_SWITCHANIM_CUSTOMER(0xEF)开始递增,且小于LV_SWITCHANIM_DEFAULT(0xFF),

2 注册动画回调

动画注册主要通过宏BUILTIN_ANIMATION注册,该宏定义如下:

#define BUILTIN_ANIMATION(anim_name,anim_major, anim_progress_cb)
anim_name : 动画名称 anim_major: 动画主ID anim_progress_cb :动画回调函数

下面以缩放动画为案例说明该流程

static void lv_zoomanim_progress(lv_baseanim_t *baseanim, lv_obj_t *anim_obj, int32_t progress)
{
	//缩放动画参数获取
    lv_baseanim_para_t *para = lv_baseanim_get_para(baseanim);
    uint16_t minor = para->minor;
    lv_coord_t zoom_start = APP_TRANS_ANIM_ZOOM_NONE;
    lv_coord_t zoom_end = 0;
    lv_coord_t opa_start = LV_OPA_COVER;
    lv_coord_t opa_end = LV_OPA_30;
	
	//更具次设备号区分不同的子动画
    if (LV_ZOOMANIM_LARGER == para->minor)
    {
        zoom_start = APP_TRANS_ANIM_ZOOM_NONE;
        zoom_end = APP_TRANS_ANIM_ZOOM_NONE << 2;
        opa_start = LV_OPA_COVER;
        opa_end = LV_OPA_30;
    }
	//动画主要分为进场动画和出场动画,每种方式单独处理
    if (LV_BASEANIM_ENTER_TYPE == lv_baseanim_get_type(baseanim))
    {
        LV_COORD_SWAP(zoom_start, zoom_end);
        LV_COORD_SWAP(opa_start, opa_end);
    }
	
	//缩放具体执行函数
    lv_coord_t zoom = lv_map(progress, 0, LV_SWITCHANIM_PROGRESS_MAX, zoom_start, zoom_end);
    lv_img_set_zoom(anim_obj, zoom);
    lv_coord_t opa = lv_map(progress, 0, LV_SWITCHANIM_PROGRESS_MAX, opa_start, opa_end);
    lv_obj_set_style_img_opa(anim_obj, opa, 0);
    lv_obj_invalidate(lv_scr_act());
}

//具体动画注册,包含动画主ID号以及回调处理函数
BUILTIN_ANIMATION(zoomanim, LV_SWITCHANIM_ZOOM, lv_zoomanim_progress);

FAQ5 如何添加指定页面动画

1 调用框架接口指定动画类型

指定页面的切换动画主要设置进场动画类型和出场动画类型,分别调用以下接口

void gui_app_set_enter_anim_type(uint16_t major, uint16_t minor, int16_t minor_aux)
	//major:动画主ID号
	//minor:动画次ID号
	//minor_aux:与之匹配另一个出场页面的动画次ID

void gui_app_set_exit_anim_type(uint16_t major, uint16_t minor, int16_t minor_aux)
	//major:动画主ID号
	//minor:动画次ID号
	//minor_aux:与之匹配另一个进场页面的动画次ID

2 配置合适的动画优先级

页面切换过程中,如A页面切到B页面。动画框架会先比较两个页面所配置动画的优先级,**最终会使用优先级高的动画类型**,如果两个优先级相等,则使用上一级页面的动画类型
void gui_app_set_anim_prior(int16_t enter_prior, int16_t exit_prior)
enter_prior:	进场动画优先级 
exit_prior:		出场动画优先级

FAQ6 如何关闭进场动画

1 调用框架接口关闭动画

关闭切换动画直接在框架接口函数on_start中调用void gui_app_close_anim()函数,该函数主要将进出动画类型设置为LV_SWITCHANIM_NONE,且优先级降为最高。