How to best structure different "screens" that share an object

Best way to structure different “screens” that share an object?

What MCU/Processor/Board and compiler are you using?

PC Sim with platformIO

What LVGL version are you using?

7.9.1

What do you want to achieve?

As seen in the screenshot, the final GUI should contain a navbar + a content screen. The navbar remains constant while the content can change, something like a sticky header in a website. However, I am not able to set screen transparency and recreating the navbar when the content changes may not be ideal.

Can anyone advise what is the best way to achieve my goal?

Ideal scenario:

What have you tried so far?

Initial approach:
Create the navbar container + the respective content in a container altogether in 1 screen. When I switch to content #2, the navbar gets recreated again.

/*pseudo code*/
// Upon power on
lv_navbar_init();
lv_content_1_init();

// if some button is toggled
lv_navbar_init();
lv_content_2_init();

Presumably a better approach:
However, I thought that a better alternative would be to initialize the navbar in a screen, the contents in another screen and overlay them like in the screenshot above.

But based on what I know, screen transparency is not available on 16bit color displays. I did attempt to set screens to be transparent on the pc simulator with the following settings:

  • lv_style_set_bg_opa(&styles->scr, LV_STATE_DEFAULT, 0)
  • set display opacity to 0 via lv_disp_set_bg_opa()

and I got this

image

Code to reproduce

Ideally, one should see both SCR1 at the top left and SCR2 in the middle.

    lv_obj_t * scr = lv_obj_create(NULL, NULL);
    lv_obj_t *scr_label = lv_label_create(scr, NULL);
    lv_label_set_text(scr_label, "SCR1");

    lv_obj_t * scr1 = lv_obj_create(NULL, NULL);
    lv_obj_t *scr_label2 = lv_label_create(scr1, NULL);
    lv_label_set_text(scr_label2, "SCR2");
    lv_obj_align(scr_label2, NULL, LV_ALIGN_CENTER, 0, 0);

    lv_scr_load(scr);
    lv_scr_load(scr1);

Hello, I’m new to LVGL, and working on as application which has some similarities, and hope this might help. We have a shared header at the top, and about 20 screens which are driven by the top header menu bar, in combination with another top tab, and/or a bottom tab as needed.

This worked for me:

  1. created a header with icons on the active screen. To use custom icons and spacing etc, I used a custom layout that calls tabs (where the tabs are hidden), instead of actually showing the tabs. Basically, clicking a navigation icon loads a tab.

  2. then on each of the parent tabs, there are different tabs/button matrix as needed to control the content on the parent tab. On each of those tabs, I created a main container that takes up the whole tab.

3)All the pages’s objects are placed into the container so I can easily show/hide the container as needed for page navigation.

Rather than using transparency, the header is created once and stays at the top of the active screen, while tab controls and show/hide containers are used to change the content below the header.

Hope this helps!

Firstly, be aware that you can only have 1 screen loaded at any given time so your transparency experiment will not work. Secondly, everything in LVGL needs a parent (except a screen).
In order to achieve what you are after you must first create the initial page (Nav bar with Content 1) then when you switch to the next page you can reassign the parent of the Nav bar using lv_obj_set_parent to screen #2. To adjust the order of children you can use lv_obj_move_foreground/lv_obj_move_background, i.e. to move the Nav bar to the top.
I think this coupled with the @jstilley approach should give you enough options to construct your UI.

Note: transparency/opacity does work for 16bit with objects on the same screen.

1 Like

Appreciate for highlighting my wrong assumptions. Will look into your suggestions!

Interesting workaround! I didn’t consider tabview objs as I thought having two separate “screens” will easier to manage.

There are generally three solutions for LVGL’s multi-page implementation:

1> Create each page individually, usinglv_scr_load() to switch between them

2> With tile_view, each selection window is a page, easy to jump to, with animation effect

3> Create each page dynamically.Compared with the above two schemes, this approach occupies less system resources, but it will increase the workload of the design switching logic.

One of my current projects is based on the third approach.Fixed status bar + multiple pages.

Above is just my personal view, hope to be helpful to you.