List (lv_list)

Overview

The List is basically a rectangle with vertical layout to which Buttons and Texts can be added

Parts and Styles

Background

  • LV_PART_MAIN The main part of the list that uses all the typical background properties

  • LV_PART_SCROLLBAR The scrollbar. See the Base objects documentation for details.

Buttons and Texts See the Button's and Label's documentation.

Usage

Buttons

lv_list_add_btn(list, icon, text) adds a full-width button with an icon - that can be an image or symbol - and a text.

The text starts to scroll horizontally if it's too long.

Texts

lv_list_add_text(list, text) adds a text.

Events

No special events are sent by the List, but sent by the Button as usual.

Learn more about Events.

Keys

No Keys are processed by the object type.

Learn more about Keys.

Example

Simple List

C code  

 GitHub
#include "../../lv_examples.h"
#if LV_USE_LIST && LV_BUILD_EXAMPLES
static lv_obj_t * list1;

static void event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * obj = lv_event_get_target(e);
    if(code == LV_EVENT_CLICKED) {
        LV_LOG_USER("Clicked: %s", lv_list_get_btn_text(list1, obj));
    }
}

void lv_example_list_1(void)
{
    /*Create a list*/
    list1 = lv_list_create(lv_scr_act());
    lv_obj_set_size(list1, 180, 220);
    lv_obj_center(list1);

    /*Add buttons to the list*/
    lv_obj_t * btn;

    lv_list_add_text(list1, "File");
    btn = lv_list_add_btn(list1, LV_SYMBOL_FILE, "New");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
    btn = lv_list_add_btn(list1, LV_SYMBOL_DIRECTORY, "Open");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
    btn = lv_list_add_btn(list1, LV_SYMBOL_SAVE, "Save");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
    btn = lv_list_add_btn(list1, LV_SYMBOL_CLOSE, "Delete");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
    btn = lv_list_add_btn(list1, LV_SYMBOL_EDIT, "Edit");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);

    lv_list_add_text(list1, "Connectivity");
    btn = lv_list_add_btn(list1, LV_SYMBOL_BLUETOOTH, "Bluetooth");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
    btn = lv_list_add_btn(list1, LV_SYMBOL_GPS, "Navigation");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
    btn = lv_list_add_btn(list1, LV_SYMBOL_USB, "USB");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
    btn = lv_list_add_btn(list1, LV_SYMBOL_BATTERY_FULL, "Battery");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);

    lv_list_add_text(list1, "Exit");
    btn = lv_list_add_btn(list1, LV_SYMBOL_OK, "Apply");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
    btn = lv_list_add_btn(list1, LV_SYMBOL_CLOSE, "Close");
    lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
}

#endif

MicroPython code  

 GitHub Simulator
def event_handler(e):
    code = e.get_code()
    obj = e.get_target()
    if code == lv.EVENT.CLICKED:
            print("Clicked: list1." + list1.get_btn_text(obj))

# Create a list
list1 = lv.list(lv.scr_act())
list1.set_size(180, 220)
list1.center()

# Add buttons to the list
list1.add_text("File")
btn_new = list1.add_btn(lv.SYMBOL.FILE, "New")
btn_new.add_event_cb(event_handler,lv.EVENT.ALL, None)
btn_open = list1.add_btn(lv.SYMBOL.DIRECTORY, "Open")
btn_open.add_event_cb(event_handler,lv.EVENT.ALL, None)
btn_save = list1.add_btn(lv.SYMBOL.SAVE, "Save")
btn_save.add_event_cb(event_handler,lv.EVENT.ALL, None)
btn_delete = list1.add_btn(lv.SYMBOL.CLOSE, "Delete")
btn_delete.add_event_cb(event_handler,lv.EVENT.ALL, None)
btn_edit = list1.add_btn(lv.SYMBOL.EDIT, "Edit")
btn_edit.add_event_cb(event_handler,lv.EVENT.ALL, None)

list1.add_text("Connectivity")
btn_bluetooth = list1.add_btn(lv.SYMBOL.BLUETOOTH, "Bluetooth")
btn_bluetooth.add_event_cb(event_handler,lv.EVENT.ALL, None)
btn_navig = list1.add_btn(lv.SYMBOL.GPS, "Navigation")
btn_navig.add_event_cb(event_handler,lv.EVENT.ALL, None)
btn_USB = list1.add_btn(lv.SYMBOL.USB, "USB")
btn_USB.add_event_cb(event_handler,lv.EVENT.ALL, None)
btn_battery = list1.add_btn(lv.SYMBOL.BATTERY_FULL, "Battery")
btn_battery.add_event_cb(event_handler,lv.EVENT.ALL, None)

list1.add_text("Exit")
btn_apply = list1.add_btn(lv.SYMBOL.OK, "Apply")
btn_apply.add_event_cb(event_handler,lv.EVENT.ALL, None)
btn_close = list1.add_btn(lv.SYMBOL.CLOSE, "Close")
btn_close.add_event_cb(event_handler,lv.EVENT.ALL, None)


Sorting a List using up and down buttons

C code  

 GitHub
#include <stdlib.h>


#include "../../lv_examples.h"
#if LV_USE_LIST && LV_BUILD_EXAMPLES

static lv_obj_t* list1;
static lv_obj_t* list2;

static lv_obj_t* currentButton = NULL;

static void event_handler(lv_event_t* e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t* obj = lv_event_get_target(e);
    if (code == LV_EVENT_CLICKED)
    {
        LV_LOG_USER("Clicked: %s", lv_list_get_btn_text(list1, obj));

        if (currentButton == obj)
        {
            currentButton = NULL;
        }
        else
        {
            currentButton = obj;
        }
        lv_obj_t* parent = lv_obj_get_parent(obj);
        uint32_t i;
        for (i = 0; i < lv_obj_get_child_cnt(parent); i++)
        {
            lv_obj_t* child = lv_obj_get_child(parent, i);
            if (child == currentButton)
            {
                lv_obj_add_state(child, LV_STATE_CHECKED);
            }
            else
            {
                lv_obj_clear_state(child, LV_STATE_CHECKED);
            }
        }
    }
}

static void event_handler_top(lv_event_t* e)
{
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_CLICKED)
    {
        if (currentButton == NULL) return;
        lv_obj_move_background(currentButton);
        lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
    }
}

static void event_handler_up(lv_event_t* e)
{
    lv_event_code_t code = lv_event_get_code(e);
    if ((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT))
    {
        if (currentButton == NULL) return;
        uint32_t index = lv_obj_get_index(currentButton);
        if (index <= 0) return;
        lv_obj_move_to_index(currentButton, index - 1);
        lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
    }
}

static void event_handler_center(lv_event_t* e)
{
    const lv_event_code_t code = lv_event_get_code(e);
    if ((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT))
    {
        if (currentButton == NULL) return;

        lv_obj_t* parent = lv_obj_get_parent(currentButton);
        const uint32_t pos = lv_obj_get_child_cnt(parent) / 2;

        lv_obj_move_to_index(currentButton, pos);

        lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
    }
}

static void event_handler_dn(lv_event_t* e)
{
    const lv_event_code_t code = lv_event_get_code(e);
    if ((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT))
    {
        if (currentButton == NULL) return;
        const uint32_t index = lv_obj_get_index(currentButton);

        lv_obj_move_to_index(currentButton, index + 1);
        lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
    }
}

static void event_handler_bottom(lv_event_t* e)
{
    const lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_CLICKED)
    {
        if (currentButton == NULL) return;
        lv_obj_move_foreground(currentButton);
        lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
    }
}

static void event_handler_swap(lv_event_t* e)
{
    const lv_event_code_t code = lv_event_get_code(e);
    // lv_obj_t* obj = lv_event_get_target(e);
    if ((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT))
    {
        uint32_t cnt = lv_obj_get_child_cnt(list1);
        for (int i = 0; i < 100; i++)
            if (cnt > 1)
            {
                lv_obj_t* obj = lv_obj_get_child(list1, rand() % cnt);
                lv_obj_move_to_index(obj, rand() % cnt);
                if (currentButton != NULL)
                {
                    lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
                }
            }
    }
}

void lv_example_list_2(void)
{
    /*Create a list*/
    list1 = lv_list_create(lv_scr_act());
    lv_obj_set_size(list1, lv_pct(60), lv_pct(100));
    lv_obj_set_style_pad_row(list1, 5, 0);

    /*Add buttons to the list*/
    lv_obj_t* btn;
    int i;
    for (i = 0; i < 15; i++) {
        btn = lv_btn_create(list1);
        lv_obj_set_width(btn, lv_pct(50));
        lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);

        lv_obj_t* lab = lv_label_create(btn);
        lv_label_set_text_fmt(lab, "Item %d", i);
    }

    /*Select the first button by default*/
    currentButton = lv_obj_get_child(list1, 0);
    lv_obj_add_state(currentButton, LV_STATE_CHECKED);

    /*Create a second list with up and down buttons*/
    list2 = lv_list_create(lv_scr_act());
    lv_obj_set_size(list2, lv_pct(40), lv_pct(100));
    lv_obj_align(list2, LV_ALIGN_TOP_RIGHT, 0, 0);
    lv_obj_set_flex_flow(list2, LV_FLEX_FLOW_COLUMN);

    btn = lv_list_add_btn(list2, NULL, "Top");
    lv_obj_add_event_cb(btn, event_handler_top, LV_EVENT_ALL, NULL);
    lv_group_remove_obj(btn);

    btn = lv_list_add_btn(list2, LV_SYMBOL_UP, "Up");
    lv_obj_add_event_cb(btn, event_handler_up, LV_EVENT_ALL, NULL);
    lv_group_remove_obj(btn);

    btn = lv_list_add_btn(list2, LV_SYMBOL_LEFT, "Center");
    lv_obj_add_event_cb(btn, event_handler_center, LV_EVENT_ALL, NULL);
    lv_group_remove_obj(btn);

    btn = lv_list_add_btn(list2, LV_SYMBOL_DOWN, "Down");
    lv_obj_add_event_cb(btn, event_handler_dn, LV_EVENT_ALL, NULL);
    lv_group_remove_obj(btn);

    btn = lv_list_add_btn(list2, NULL, "Bottom");
    lv_obj_add_event_cb(btn, event_handler_bottom, LV_EVENT_ALL, NULL);
    lv_group_remove_obj(btn);

    btn = lv_list_add_btn(list2, LV_SYMBOL_SHUFFLE, "Shuffle");
    lv_obj_add_event_cb(btn, event_handler_swap, LV_EVENT_ALL, NULL);
    lv_group_remove_obj(btn);
}

#endif

MicroPython code  

 GitHub Simulator
import urandom

currentButton = None
list1 = None

def event_handler(evt):
    global currentButton
    code = evt.get_code()
    obj = evt.get_target()
    if code == lv.EVENT.CLICKED:
        if currentButton == obj:
            currentButton = None
        else:
            currentButton = obj
        parent = obj.get_parent()
        for i in range( parent.get_child_cnt()):
            child = parent.get_child(i)
            if child == currentButton:
                child.add_state(lv.STATE.CHECKED)
            else:
                child.clear_state(lv.STATE.CHECKED)

def event_handler_top(evt):
    global currentButton
    code = evt.get_code()
    obj = evt.get_target()
    if code == lv.EVENT.CLICKED:
        if currentButton == None:
            return
        currentButton.move_background()
        currentButton.scroll_to_view( lv.ANIM.ON)

def event_handler_up(evt):
    global currentButton
    code = evt.get_code()
    obj = evt.get_target()
    if code == lv.EVENT.CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
        if currentButton == None:
            return
        index = currentButton.get_index()
        if index <= 0:
            return
        currentButton.move_to_index(index - 1)
        currentButton.scroll_to_view(lv.ANIM.ON)

def event_handler_center(evt):
    global currentButton
    code = evt.get_code()
    obj = evt.get_target()
    if code == lv.EVENT.CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
        if currentButton == None:
            return
        parent = currentButton.get_parent()
        pos = parent.get_child_cnt() // 2
        currentButton.move_to_index(pos)
        currentButton.scroll_to_view(lv.ANIM.ON)

def event_handler_dn(evt):
    global currentButton
    code = evt.get_code()
    obj = evt.get_target()
    if code == lv.EVENT.CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
        if currentButton == None:
            return
        index = currentButton.get_index()
        currentButton.move_to_index(index + 1)
        currentButton.scroll_to_view(lv.ANIM.ON)

def event_handler_bottom(evt):
    global currentButton
    code = evt.get_code()
    obj = evt.get_target()
    if code == lv.EVENT.CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
        if currentButton == None:
            return
        currentButton.move_foreground()
        currentButton.scroll_to_view(lv.ANIM.ON)

def event_handler_swap(evt):
    global currentButton
    global list1
    code = evt.get_code()
    obj = evt.get_target()
    if code == lv.EVENT.CLICKED:    
        cnt = list1.get_child_cnt()
        for i in range(100):
            if cnt > 1:
                obj = list1.get_child(urandom.getrandbits(32) % cnt )
                obj.move_to_index(urandom.getrandbits(32) % cnt)
        if currentButton != None:
            currentButton.scroll_to_view(lv.ANIM.ON)
                
#Create a list with buttons that can be sorted
list1 = lv.list(lv.scr_act())
list1.set_size(lv.pct(60), lv.pct(100))
list1.set_style_pad_row( 5, 0)

for i in range(15):
    btn = lv.btn(list1)
    btn.set_width(lv.pct(100))
    btn.add_event_cb( event_handler, lv.EVENT.CLICKED, None)
    lab = lv.label(btn)
    lab.set_text("Item " + str(i))

#Select the first button by default
currentButton = list1.get_child(0)
currentButton.add_state(lv.STATE.CHECKED)

#Create a second list with up and down buttons
list2 = lv.list(lv.scr_act())
list2.set_size(lv.pct(40), lv.pct(100))
list2.align(lv.ALIGN.TOP_RIGHT, 0, 0)
list2.set_flex_flow(lv.FLEX_FLOW.COLUMN)

btn = list2.add_btn(None, "Top")
btn.add_event_cb(event_handler_top, lv.EVENT.ALL, None)
lv.group_remove_obj(btn)

btn = list2.add_btn(lv.SYMBOL.UP, "Up")
btn.add_event_cb(event_handler_up, lv.EVENT.ALL, None)
lv.group_remove_obj(btn)

btn = list2.add_btn(lv.SYMBOL.LEFT, "Center")
btn.add_event_cb(event_handler_center, lv.EVENT.ALL, None)
lv.group_remove_obj(btn)

btn = list2.add_btn(lv.SYMBOL.DOWN, "Down")
btn.add_event_cb(event_handler_dn, lv.EVENT.ALL, None)
lv.group_remove_obj(btn)

btn = list2.add_btn(None, "Bottom")
btn.add_event_cb(event_handler_bottom, lv.EVENT.ALL, None)
lv.group_remove_obj(btn)

btn = list2.add_btn(lv.SYMBOL.SHUFFLE, "Shuffle")
btn.add_event_cb(event_handler_swap, lv.EVENT.ALL, None)
lv.group_remove_obj(btn)

API

Functions

lv_obj_t *lv_list_create(lv_obj_t *parent)
lv_obj_t *lv_list_add_text(lv_obj_t *list, const char *txt)
lv_obj_t *lv_list_add_btn(lv_obj_t *list, const char *icon, const char *txt)
const char *lv_list_get_btn_text(lv_obj_t *list, lv_obj_t *btn)

Variables

const lv_obj_class_t lv_list_class
const lv_obj_class_t lv_list_text_class
const lv_obj_class_t lv_list_btn_class