在单片机中显示动画是一件很浪费资源的事情,在那个小小的flash中存入一大坨数据是相当费力地,因此就进度条动画而言,有一种相当简单的实现方式,就是重复移动整个图片然后遮住某个部分,例如这个样子:

1.gif

动图中可以看到在被遮住后,达到了动画的效果

实现该功能并且封装成函数:

/*
*函数说明:这个函数用来在屏幕上显示进度条动画,旨在节省资源
*参数传入:1、父对象;2、图片内容3、原始图片被分成几部分了(备注详谈)4、布局
*返回值:无
*备注:这个动画的实现方式是对一张图片进行循环动画,并对其能看到运动的地方进行遮罩
*此函数对图片的格式具有要求,详情参考示例图片,图片被分成几个part,运动路径为一个part。
*/
void lv_progress_bar_animation(lv_obj_t * obj,const void *src_img,int part,lv_align_t align)
{
    float mask_w=(float)(part-1)/(float)part;//某些系数的计算
    float anim=(float)(((float)1/(float)part));

    lv_obj_t *parent=obj;//父布局继承
    lv_obj_t * cont = lv_cont_create(parent, NULL);//新建一个容器
    lv_img_header_t header; //新建一个图片头部对象
    lv_img_decoder_get_info(src_img, &header);
    lv_obj_set_size(cont, header.w*mask_w,header.h);//设定容器的宽度为图片的宽度*系数,容器的高度为图片的高度
    lv_obj_align(cont, NULL, align, 0, 0);//设置容器位于父布局的位置

    lv_obj_set_style_local_border_width(cont,LV_CONT_PART_MAIN,LV_STATE_DEFAULT,0);//隐藏容器的边框
    lv_obj_t * img1 = lv_img_create(cont, NULL);//建立一个图片对象
    lv_img_set_src(img1, src_img);//设定图片的内容


    lv_anim_t a;   //新建动画
    lv_anim_init(&a);//初始化动画
    lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) lv_obj_set_x);//设定动画回调函数
    lv_anim_set_var(&a, img1);//给动画绑定图片对象
    lv_anim_set_time(&a, 1000);//设定动画速度
    lv_anim_set_values(&a, -header.w*anim, 0);//设定动画位置从哪里到哪里
    lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);//设置动画永不停息
    lv_anim_start(&a);//动画开始
}

在函数中调用:

LV_IMG_DECLARE(slider);
lv_progress_bar_animation(lv_scr_act(),&slider,4,LV_ALIGN_CENTER);

LV_IMG_DECLARE(bar);
lv_progress_bar_animation(lv_scr_act(),&bar,7,LV_ALIGN_IN_BOTTOM_MID);

实现效果如下:

2.gif

重点讲一下这里的part参数:

part如何计算.png

part就是有几个重复的部分,并且动画播放时,运动的路径为-一个part的像素到0.然后将末端遮住就可以了。