Scrolling

Scroll-enabled containers and content.

Report on GitHub

Any lv_obj_t whose content exceeds its bounds can scroll, with per-axis control and optional snap points that lock motion to child boundaries. Scrollbars are themeable through the LV_PART_SCROLLBAR style part, and event callbacks let you translate, fade, or scale children as they move through the viewport. The examples demonstrate snapped paging, custom scrollbar styling, parallax-style translation, and an infinite scroll pattern.

Automatic scrolling and save/restore

Log scroll metrics on a 200x200 panel and save or restore its scroll position.

A panel is placed on the active screen with three children positioned outside its bounds so scrolling is needed to reach them. A callback on LV_EVENT_SCROLL logs lv_obj_get_scroll_x/y/top/bottom/left/right. Two buttons aligned with LV_ALIGN_OUT_LEFT_MID capture and replay the scroll position via lv_obj_scroll_to with LV_ANIM_ON.

Horizontal scroll snap with opt-out

Snap a row of ten panels to center, skip one panel, and toggle one-at-a-time scrolling.

A 280x120 flex-row panel uses lv_obj_set_scroll_snap_x(panel, LV_SCROLL_SNAP_CENTER) so each 150 px button centers as it scrolls past. Panel 3 removes LV_OBJ_FLAG_SNAPPABLE so scrolling skips over it. A switch aligned at the top right toggles LV_OBJ_FLAG_SCROLL_ONE on the panel, restricting scroll gestures to one panel at a time when checked.

Floating add button over list

Keep a circular plus button pinned to a scrollable list while it adds track entries.

A 280x220 lv_list is seeded with two LV_SYMBOL_AUDIO track entries. A child button given LV_OBJ_FLAG_FLOATING and LV_RADIUS_CIRCLE is aligned to LV_ALIGN_BOTTOM_RIGHT so it stays over the list while it scrolls. Clicking the floating button appends a new "Track N" entry, moves itself back to the foreground with lv_obj_move_to_index, and calls lv_obj_scroll_to_view with LV_ANIM_ON to reveal the new row.

Styled scrollbar with state transition

Restyle the LV_PART_SCROLLBAR of a text panel and fade it in while scrolling.

A 200x100 container holds a long Lorem Ipsum label. The default scrollbar style is removed, then a custom lv_style_t sets width 4, length 20, padding, radius 2, LV_OPA_70 blue fill, a darker blue border, and a shadow. A second style tied to LV_STATE_SCROLLED widens the scrollbar to 8 and sets LV_OPA_COVER, and a 200 ms lv_style_transition_dsc_t over LV_STYLE_BG_OPA and LV_STYLE_WIDTH animates between the two states.

RTL label scrolling

Scroll a wide Persian label inside an RTL container.

A 200x100 container has LV_BASE_DIR_RTL applied to its main part. A child label 400 px wide, rendered with lv_font_dejavu_16_persian_hebrew, carries a Persian paragraph; the scrollbar and scroll direction reflect the right-to-left base direction as the label is dragged.

Circular scroll translate effect

Bow a column of buttons along a circle while they scroll past center.

A 200x200 container is given LV_RADIUS_CIRCLE, clip_corner, LV_FLEX_FLOW_COLUMN, LV_SCROLL_SNAP_CENTER on Y, and LV_SCROLLBAR_MODE_OFF. Twenty full-width buttons are scrolled vertically. An LV_EVENT_SCROLL callback computes each child's vertical offset from the container center, maps it onto a circle with radius 7/10 of the height via lv_sqrt, writes the result to translate_x, and fades children with larger offsets toward LV_OPA_TRANSP.

Virtualized infinite scroll

Load numbered rows on demand and drop far-off ones as a column is scrolled.

A 160x220 column container tracks the highest and lowest loaded numbers in top_num and bottom_num. An LV_EVENT_SCROLL callback adds items while lv_obj_get_scroll_top or lv_obj_get_scroll_bottom is under 200 and within the (-30, 30) range, and deletes items once those values exceed 600, compensating each delta with lv_obj_scroll_by so the view stays steady. Two labels report the current extremes, and a checkbox toggles LV_PART_SCROLLBAR opacity between LV_OPA_TRANSP and LV_OPA_COVER.

Endless wrap-around scroll

Wrap items from one edge to the other so a row and column scroll without limits.

Two flex containers are built: a 300x75 row and a 200x150 column, each filled with ten 80 px-sized buttons. Both register an LV_EVENT_SCROLL callback that detects when lv_obj_get_scroll_x or lv_obj_get_scroll_y reaches either edge and calls lv_obj_move_to_index to move the last or first child across, then compensates with lv_obj_scroll_to_x or lv_obj_scroll_to_y so the visible content stays stable and scrolling feels endless. Scrollbars are hidden with LV_SCROLLBAR_MODE_OFF.

Toggle scroll flags on a list

A panel of four switches enables or clears scroll behavior flags on an image list.

A shadowed panel holds a ten-entry lv_list of LV_SYMBOL_IMAGE buttons and four rows, each pairing a label with a switch. The switches are wired to LV_EVENT_VALUE_CHANGED and add or remove LV_OBJ_FLAG_SCROLLABLE, LV_OBJ_FLAG_SCROLL_CHAIN, LV_OBJ_FLAG_SCROLL_ELASTIC, and LV_OBJ_FLAG_SCROLL_MOMENTUM on the list. The list is moved to the last index so the switches appear above it.

How is this guide?

Last updated on

On this page