提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
项目开发中有如下场景:
- 需要一个页面显示历史记录
- 历史记录超过2000条
- 滚动下滑加载更多的历史记录
遇到的问题:
- 如果用普通方式(有多少条记录就创建多少个object,一次性创建),将非常占用内存。而且如果记录条数不断增加,早晚会内存不够。
解决方案:
- 采用换页方式(切换到新的页面),每次切换到新的页面,删除上一个页面的组件,在新页面继续创建新组件。这种方法可以实现,是比较简单可靠的方法,但是需要页面中创建两个按键(上一页,下一页的翻页按键)。如果界面风格与原来的界面一致,可以使用。
- 定时定时刷新的方式,根据父对象的滚动位置,实时创建该位置需要创建显示的内容,同时删除已经滚动出显示区域的内容。
本文介绍第二种方法。
提示:以下是本篇文章正文内容,下面案例可供参考
一、代码示例
/* 说明:
* 1. 屏幕高度:600像素。
* 2. 当下滑超过600像素时,刷新下方组件的内容和位置。
* 3. 上划超过UP_REFRESH_PX的时候,刷新上方组件的内容和位置,可以调整UP_REFRESH_PX的值,来调整刷新频率和灵敏度。
* 4. REFRESH_TIME_MS调节刷新的频率,默认1000ms.
* 5. 总共创建30个对象循环显示所有的内容,内存中只占用这30个对象的内容。
*/
#define SCREEN_HEIGHT (600)
#define OBJ_HEIGHT (70)
#define OBJ_GROUP_CNT (10)
#define OBJ_GROUP_HEIGHT (OBJ_GROUP_CNT*OBJ_HEIGHT)
#define UP_REFRESH_PX (-100)
#define REFRESH_TIME_MS (1000)
static lv_obj_t * obj3[30] = {NULL};
static lv_obj_t * my_scroll = NULL;
int last_pos = 0;
/* 定时刷新 */
static void scroll_timer_cb(lv_timer_t * t)
{
int pos = lv_obj_get_scroll_y(my_scroll);
int idx = pos/OBJ_GROUP_HEIGHT;
printf("y:%d %d\n", pos, last_pos);
if(pos - last_pos > SCREEN_HEIGHT)
{
last_pos = pos;
for(int i=0; i<30; i++)
{
lv_label_set_text_fmt(lv_obj_get_child(obj3[i], 0), "%d", idx*10+i);
lv_obj_align(obj3[i], LV_ALIGN_OUT_TOP_MID, 0, idx*OBJ_GROUP_HEIGHT+i*OBJ_HEIGHT);
}
}
else if(pos - last_pos < UP_REFRESH_PX && pos > 0)
{
last_pos = pos;
if(idx > 0) idx -= 1;
for(int i=0; i<30; i++)
{
lv_label_set_text_fmt(lv_obj_get_child(obj3[i], 0), "%d", idx*10+i);
lv_obj_align(obj3[i], LV_ALIGN_OUT_TOP_MID, 0, idx*OBJ_GROUP_HEIGHT+i*OBJ_HEIGHT);
}
}
}
/* 创建scroll */
static lv_obj_t * big_scroll(lv_obj_t * parent)
{
lv_obj_t * main_cont = lv_obj_create(parent);
lv_obj_set_size(main_cont, lv_pct(100), lv_pct(100));
lv_obj_t * my_scroll = lv_obj_create(main_cont);
lv_obj_set_size(my_scroll, lv_pct(20), lv_pct(100));
for(int i=0; i<30; i++)
{
obj3[i] = lv_obj_create(my_scroll);
lv_obj_set_size(obj3[i], lv_pct(100), OBJ_HEIGHT);
lv_obj_align(obj3[i], LV_ALIGN_OUT_TOP_MID, 0, OBJ_HEIGHT*i);
lv_obj_t * lb = lv_label_create(obj3[i]);
lv_label_set_text_fmt(lb, "%d", i);
}
return my_scroll;
}
/* 使用方法 */
void main(void)
{
my_scroll = big_scroll(lv_scr_act());
lv_timer_t * scroll_timer = lv_timer_create(scroll_timer_cb, REFRESH_TIME_MS, NULL);
}
二、测试效果
持续下滑,仅占用28.5kB内存。
备注:lv_conf.h中的宏LV_USE_LARGE_COORD设置为1,这样坐标可以扩充到int32_t。
/*Extend the default -32k..32k coordinate range to -4M..4M by using int32_t for coordinates instead of int16_t*/
#define LV_USE_LARGE_COORD 1