mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-26 11:07:34 +08:00
feat(examples): add looping scroll example (#7714)
Co-authored-by: lizhaoming <13678462+lizhao-ming@user.noreply.gitee.com>
This commit is contained in:
@@ -34,5 +34,10 @@ Infinite scrolling
|
||||
------------------
|
||||
.. lv_example:: scroll/lv_example_scroll_7
|
||||
:language: c
|
||||
|
||||
circular scrolling
|
||||
------------------
|
||||
.. lv_example:: scroll/lv_example_scroll_8
|
||||
:language: c
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ void lv_example_scroll_4(void);
|
||||
void lv_example_scroll_5(void);
|
||||
void lv_example_scroll_6(void);
|
||||
void lv_example_scroll_7(void);
|
||||
void lv_example_scroll_8(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES && LV_USE_FLEX
|
||||
|
||||
|
||||
/*
|
||||
* Circular list implementation based on:
|
||||
* Reference: https://blog.csdn.net/TQW4321/article/details/145434819
|
||||
*/
|
||||
|
||||
/* Applies to both width (for row items) and height (for column items) */
|
||||
#define ITEM_SIZE 80
|
||||
|
||||
/* Function to calculate the total content width of the container */
|
||||
static int32_t get_content_width(lv_obj_t * cont)
|
||||
{
|
||||
int32_t w = 0;
|
||||
int32_t pad_column = lv_obj_get_style_pad_column(cont, LV_PART_MAIN); // 列间距
|
||||
int total = lv_obj_get_child_count(cont);
|
||||
|
||||
for(int i = 0; i < total; i++) {
|
||||
w += lv_obj_get_width(lv_obj_get_child(cont, i));
|
||||
if(i < total - 1) w += pad_column;
|
||||
}
|
||||
return w + lv_obj_get_style_pad_left(cont, LV_PART_MAIN)
|
||||
+ lv_obj_get_style_pad_right(cont, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
/* Scroll event callback for row layout */
|
||||
static void cont_row_scroll_event_cb(lv_event_t * e)
|
||||
{
|
||||
static bool is_adjusting = false;
|
||||
lv_obj_t * cont = lv_event_get_current_target_obj(e);
|
||||
|
||||
if(!is_adjusting) {
|
||||
is_adjusting = true;
|
||||
int32_t scroll_x = lv_obj_get_scroll_x(cont);
|
||||
int32_t cont_w = lv_obj_get_width(cont);
|
||||
int32_t content_w = get_content_width(cont);
|
||||
|
||||
/* Use ITEM_SIZE as horizontal item width */
|
||||
const int32_t item_width = ITEM_SIZE;
|
||||
|
||||
if(scroll_x <= 0) {
|
||||
lv_obj_t * last_child = lv_obj_get_child(cont, lv_obj_get_child_count(cont) - 1);
|
||||
lv_obj_move_to_index(last_child, 0);
|
||||
lv_obj_scroll_to_x(cont, scroll_x + item_width, LV_ANIM_OFF);
|
||||
}
|
||||
else if(scroll_x > content_w - cont_w) {
|
||||
lv_obj_t * first_child = lv_obj_get_child(cont, 0);
|
||||
lv_obj_move_to_index(first_child, lv_obj_get_child_count(cont) - 1);
|
||||
lv_obj_scroll_to_x(cont, scroll_x - item_width, LV_ANIM_OFF);
|
||||
}
|
||||
is_adjusting = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to calculate the total content height of the container */
|
||||
static int32_t get_content_height(lv_obj_t * cont)
|
||||
{
|
||||
int32_t h = 0;
|
||||
int32_t pad_row = lv_obj_get_style_pad_row(cont, LV_PART_MAIN);
|
||||
int total = lv_obj_get_child_count(cont);
|
||||
|
||||
for(int i = 0; i < total; i++) {
|
||||
h += lv_obj_get_height(lv_obj_get_child(cont, i));
|
||||
if(i < total - 1) h += pad_row;
|
||||
}
|
||||
return h + lv_obj_get_style_pad_top(cont, LV_PART_MAIN)
|
||||
+ lv_obj_get_style_pad_bottom(cont, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
/* Scroll event callback for column layout */
|
||||
static void cont_col_scroll_event_cb(lv_event_t * e)
|
||||
{
|
||||
static bool is_adjusting = false;
|
||||
lv_obj_t * cont = lv_event_get_current_target_obj(e);
|
||||
|
||||
if(!is_adjusting) {
|
||||
is_adjusting = true;
|
||||
int32_t scroll_y = lv_obj_get_scroll_y(cont);
|
||||
int32_t cont_h = lv_obj_get_height(cont);
|
||||
int32_t content_h = get_content_height(cont);
|
||||
|
||||
/* Use ITEM_SIZE as vertical item height */
|
||||
const int32_t item_height = ITEM_SIZE;
|
||||
|
||||
if(scroll_y <= 0) {
|
||||
lv_obj_t * last_child = lv_obj_get_child(cont, lv_obj_get_child_count(cont) - 1);
|
||||
lv_obj_move_to_index(last_child, 0);
|
||||
lv_obj_scroll_to_y(cont, scroll_y + item_height, LV_ANIM_OFF);
|
||||
}
|
||||
else if(scroll_y > content_h - cont_h) {
|
||||
lv_obj_t * first_child = lv_obj_get_child(cont, 0);
|
||||
lv_obj_move_to_index(first_child, lv_obj_get_child_count(cont) - 1);
|
||||
lv_obj_scroll_to_y(cont, scroll_y - item_height, LV_ANIM_OFF);
|
||||
}
|
||||
is_adjusting = false;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_example_scroll_8(void)
|
||||
{
|
||||
/* Create a scroll container with ROW flex direction */
|
||||
lv_obj_t * cont_row = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(cont_row, 300, 75);
|
||||
lv_obj_align(cont_row, LV_ALIGN_TOP_MID, 0, 5);
|
||||
lv_obj_set_flex_flow(cont_row, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_add_event_cb(cont_row, cont_row_scroll_event_cb, LV_EVENT_SCROLL, NULL);
|
||||
/* Hide scrollbar visuals */
|
||||
lv_obj_set_scrollbar_mode(cont_row, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
/* Create a scroll container with COLUMN flex direction */
|
||||
lv_obj_t * cont_col = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(cont_col, 200, 150);
|
||||
lv_obj_align_to(cont_col, cont_row, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);
|
||||
lv_obj_set_flex_flow(cont_col, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_add_event_cb(cont_col, cont_col_scroll_event_cb, LV_EVENT_SCROLL, NULL);
|
||||
/* Hide scrollbar visuals */
|
||||
lv_obj_set_scrollbar_mode(cont_col, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
/* If the number of items is less than 3, scrolling may not be needed or may cause unexpected behavior. */
|
||||
uint32_t i;
|
||||
for(i = 0; i < 10; i++) {
|
||||
lv_obj_t * obj;
|
||||
lv_obj_t * label;
|
||||
|
||||
/*Add items to the row*/
|
||||
obj = lv_button_create(cont_row);
|
||||
lv_obj_set_size(obj, ITEM_SIZE, LV_PCT(100));
|
||||
|
||||
label = lv_label_create(obj);
|
||||
lv_label_set_text_fmt(label, "Item %" LV_PRIu32, i + 1);
|
||||
lv_obj_center(label);
|
||||
|
||||
/*Add items to the column*/
|
||||
obj = lv_button_create(cont_col);
|
||||
lv_obj_set_size(obj, LV_PCT(100), ITEM_SIZE);
|
||||
|
||||
label = lv_label_create(obj);
|
||||
lv_label_set_text_fmt(label, "Item %" LV_PRIu32, i + 1);
|
||||
lv_obj_center(label);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user