提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

项目开发中有如下场景:

  • 需要一个页面显示历史记录
  • 历史记录超过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

在这里插入图片描述
在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐