Fragment(片段)¶
Fragment 是从 Android 借鉴的一个概念。
它表示应用程序 UI 的一个可重用部分。Fragment 定义并管理其自己的布局,具有自己的生命周期,并可以处理自己的事件。与 Android 的 Fragment 必须由活动或另一个 Fragment 托管类似,LVGL 中的 Fragment 需要由一个对象或另一个 Fragment 托管。Fragment 的视图层次结构成为或附加到宿主的视图层次结构的一部分。
这一概念与 iOS 上的 UiViewController 也有一些相似之处。
Fragment Manager 是一个管理器,用于保存附加到它的 Fragment 的引用,并具有一个内部堆栈以实现导航。您可以使用 Fragment Manager 轻松构建导航堆栈或多窗格应用程序。
使用方法¶
在 lv_conf.h 中启用 LV_USE_FRAGMENT。
创建 Fragment 类¶
struct sample_fragment_t {
/* 重要:不要遗漏这一部分 */
lv_fragment_t base;
/* 此 Fragment 的状态、对象引用和数据字段 */
const char *title;
};
const lv_fragment_class_t sample_cls = {
/* 初始化所需内容 */
.constructor_cb = sample_fragment_ctor,
/* 创建视图对象 */
.create_obj_cb = sample_fragment_create_obj,
/* 重要:您的 Fragment 结构体的大小 */
.instance_size = sizeof(struct sample_fragment_t)
};
使用 lv_fragment_manager¶
/* 创建 Fragment 实例,对象将被添加到容器中 */
lv_fragment_manager_t *manager = lv_fragment_manager_create(container, NULL);
/* 用 sample_cls 的实例替换当前 Fragment,init_argument 是用户定义的指针 */
lv_fragment_manager_replace(manager, &sample_cls, init_argument);
基于 Fragment 的导航¶
/* 将一个实例添加到管理器堆栈中。当前 Fragment 的视图对象将被销毁,
* 但在类构造函数中创建的实例将被保留。
*/
lv_fragment_manager_push(manager, &sample_cls, NULL);
/* 从堆栈中移除最顶部的 Fragment,并恢复前一个 Fragment。 */
lv_fragment_manager_pop(manager);
示例¶
基本片段用法¶
C code
GitHub/**
* @file lv_example_fragment_1.c
* @brief Basic usage of obj fragment
*/
#include "../../lv_examples.h"
#if LV_USE_FRAGMENT && LV_BUILD_EXAMPLES
static void sample_fragment_ctor(lv_fragment_t * self, void * args);
static lv_obj_t * sample_fragment_create_obj(lv_fragment_t * self, lv_obj_t * parent);
static void sample_container_del(lv_event_t * e);
static lv_obj_t * root = NULL;
struct sample_fragment_t {
lv_fragment_t base;
const char * name;
};
static const lv_fragment_class_t sample_cls = {
.constructor_cb = sample_fragment_ctor,
.create_obj_cb = sample_fragment_create_obj,
.instance_size = sizeof(struct sample_fragment_t)
};
void lv_example_fragment_1(void)
{
root = lv_obj_create(lv_scr_act());
lv_obj_set_size(root, LV_PCT(100), LV_PCT(100));
lv_fragment_manager_t * manager = lv_fragment_manager_create(NULL);
/* Clean up the fragment manager before objects in containers got deleted */
lv_obj_add_event_cb(root, sample_container_del, LV_EVENT_DELETE, manager);
lv_fragment_t * fragment = lv_fragment_create(&sample_cls, "Fragment");
lv_fragment_manager_replace(manager, fragment, &root);
}
static void sample_fragment_ctor(lv_fragment_t * self, void * args)
{
((struct sample_fragment_t *) self)->name = args;
}
static lv_obj_t * sample_fragment_create_obj(lv_fragment_t * self, lv_obj_t * parent)
{
lv_obj_t * label = lv_label_create(parent);
lv_obj_set_style_bg_opa(label, LV_OPA_COVER, 0);;
lv_label_set_text_fmt(label, "Hello, %s!", ((struct sample_fragment_t *) self)->name);
return label;
}
static void sample_container_del(lv_event_t * e)
{
lv_fragment_manager_t * manager = (lv_fragment_manager_t *) lv_event_get_user_data(e);
lv_fragment_manager_del(manager);
}
#endif
Error encountered while trying to open D:\lv_port_pc_eclipse-release-v8.3\lvgl\examples\others\fragment\lv_example_fragment_1.py
堆栈导航示例¶
C code
GitHub/**
* @file lv_example_fragment_2.c
* @brief Navigation stack using obj fragment
*/
#include "../../lv_examples.h"
#if LV_USE_FRAGMENT && LV_USE_WIN && LV_BUILD_EXAMPLES
static void sample_fragment_ctor(lv_fragment_t * self, void * args);
static lv_obj_t * sample_fragment_create_obj(lv_fragment_t * self, lv_obj_t * parent);
static void sample_push_click(lv_event_t * e);
static void sample_pop_click(lv_event_t * e);
static void sample_container_del(lv_event_t * e);
static void sample_fragment_inc_click(lv_event_t * e);
typedef struct sample_fragment_t {
lv_fragment_t base;
lv_obj_t * label;
int depth;
int counter;
} sample_fragment_t;
static const lv_fragment_class_t sample_cls = {
.constructor_cb = sample_fragment_ctor,
.create_obj_cb = sample_fragment_create_obj,
.instance_size = sizeof(sample_fragment_t)
};
static lv_obj_t * container = NULL;
void lv_example_fragment_2(void)
{
lv_obj_t * root = lv_obj_create(lv_scr_act());
lv_obj_set_size(root, LV_PCT(100), LV_PCT(100));
lv_obj_set_layout(root, LV_LAYOUT_GRID);
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
static const lv_coord_t row_dsc[] = {LV_GRID_FR(1), LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
lv_obj_set_grid_dsc_array(root, col_dsc, row_dsc);
container = lv_obj_create(root);
lv_obj_remove_style_all(container);
lv_obj_set_grid_cell(container, LV_GRID_ALIGN_STRETCH, 0, 2, LV_GRID_ALIGN_STRETCH, 0, 1);
lv_obj_t * push_btn = lv_btn_create(root);
lv_obj_t * push_label = lv_label_create(push_btn);
lv_label_set_text(push_label, "Push");
lv_obj_t * pop_btn = lv_btn_create(root);
lv_obj_t * pop_label = lv_label_create(pop_btn);
lv_label_set_text(pop_label, "Pop");
lv_obj_set_grid_cell(push_btn, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_CENTER, 1, 1);
lv_obj_set_grid_cell(pop_btn, LV_GRID_ALIGN_END, 1, 1, LV_GRID_ALIGN_CENTER, 1, 1);
lv_fragment_manager_t * manager = lv_fragment_manager_create(NULL);
/* Clean up the fragment manager before objects in containers got deleted */
lv_obj_add_event_cb(root, sample_container_del, LV_EVENT_DELETE, manager);
int depth = 0;
lv_fragment_t * fragment = lv_fragment_create(&sample_cls, &depth);
lv_fragment_manager_push(manager, fragment, &container);
lv_obj_add_event_cb(push_btn, sample_push_click, LV_EVENT_CLICKED, manager);
lv_obj_add_event_cb(pop_btn, sample_pop_click, LV_EVENT_CLICKED, manager);
}
static void sample_fragment_ctor(lv_fragment_t * self, void * args)
{
LV_UNUSED(args);
((sample_fragment_t *) self)->depth = *((int *) args);
((sample_fragment_t *) self)->counter = 0;
}
static lv_obj_t * sample_fragment_create_obj(lv_fragment_t * self, lv_obj_t * parent)
{
sample_fragment_t * fragment = (sample_fragment_t *) self;
lv_obj_t * content = lv_obj_create(parent);
lv_obj_remove_style_all(content);
lv_obj_set_style_bg_opa(content, LV_OPA_50, 0);
lv_obj_set_style_bg_color(content, lv_palette_main(LV_PALETTE_YELLOW), 0);
lv_obj_set_size(content, LV_PCT(100), LV_PCT(100));
lv_obj_set_flex_flow(content, LV_FLEX_FLOW_COLUMN);
lv_obj_t * depth = lv_label_create(content);
lv_label_set_text_fmt(depth, "Depth: %d", fragment->depth);
lv_obj_t * label = lv_label_create(content);
fragment->label = label;
lv_label_set_text_fmt(label, "The button has been pressed %d times", fragment->counter);
lv_obj_t * inc_btn = lv_btn_create(content);
lv_obj_t * inc_label = lv_label_create(inc_btn);
lv_label_set_text(inc_label, "+1");
lv_obj_add_event_cb(inc_btn, sample_fragment_inc_click, LV_EVENT_CLICKED, fragment);
return content;
}
static void sample_push_click(lv_event_t * e)
{
lv_fragment_manager_t * manager = (lv_fragment_manager_t *) lv_event_get_user_data(e);
size_t stack_size = lv_fragment_manager_get_stack_size(manager);
lv_fragment_t * fragment = lv_fragment_create(&sample_cls, &stack_size);
lv_fragment_manager_push(manager, fragment, &container);
}
static void sample_pop_click(lv_event_t * e)
{
lv_fragment_manager_t * manager = (lv_fragment_manager_t *) lv_event_get_user_data(e);
lv_fragment_manager_pop(manager);
}
static void sample_container_del(lv_event_t * e)
{
lv_fragment_manager_t * manager = (lv_fragment_manager_t *) lv_event_get_user_data(e);
lv_fragment_manager_del(manager);
}
static void sample_fragment_inc_click(lv_event_t * e)
{
sample_fragment_t * fragment = (sample_fragment_t *) lv_event_get_user_data(e);
fragment->counter++;
lv_label_set_text_fmt(fragment->label, "The button has been pressed %d times", fragment->counter);
}
#endif
Error encountered while trying to open D:\lv_port_pc_eclipse-release-v8.3\lvgl\examples\others\fragment\lv_example_fragment_2.py
API¶
Public header for Fragment
Typedefs
-
typedef struct _lv_fragment_manager_t
lv_fragment_manager_t¶
-
typedef struct _lv_fragment_t
lv_fragment_t¶
-
typedef struct _lv_fragment_class_t
lv_fragment_class_t¶
-
typedef struct _lv_fragment_managed_states_t
lv_fragment_managed_states_t¶ Fragment states
Functions
-
lv_fragment_manager_t *
lv_fragment_manager_create(lv_fragment_t *parent)¶ Create fragment manager instance
- Parameters
parent -- Parent fragment if this manager is placed inside another fragment, can be null.
- Returns
Fragment manager instance
-
void
lv_fragment_manager_del(lv_fragment_manager_t *manager)¶ Destroy fragment manager instance
- Parameters
manager -- Fragment manager instance
-
void
lv_fragment_manager_create_obj(lv_fragment_manager_t *manager)¶ Create object of all fragments managed by this manager.
- Parameters
manager -- Fragment manager instance
-
void
lv_fragment_manager_del_obj(lv_fragment_manager_t *manager)¶ Delete object created by all fragments managed by this manager. Instance of fragments will not be deleted.
- Parameters
manager -- Fragment manager instance
-
void
lv_fragment_manager_add(lv_fragment_manager_t *manager, lv_fragment_t *fragment, lv_obj_t *const *container)¶ Attach fragment to manager, and add to container.
- Parameters
manager -- Fragment manager instance
fragment -- Fragment instance
container -- Pointer to container object for manager to add objects to
-
void
lv_fragment_manager_remove(lv_fragment_manager_t *manager, lv_fragment_t *fragment)¶ Detach and destroy fragment. If fragment is in navigation stack, remove from it.
- Parameters
manager -- Fragment manager instance
fragment -- Fragment instance
-
void
lv_fragment_manager_push(lv_fragment_manager_t *manager, lv_fragment_t *fragment, lv_obj_t *const *container)¶ Attach fragment to manager and add to navigation stack.
- Parameters
manager -- Fragment manager instance
fragment -- Fragment instance
container -- Pointer to container object for manager to add objects to
-
bool
lv_fragment_manager_pop(lv_fragment_manager_t *manager)¶ Remove the top-most fragment for stack
- Parameters
manager -- Fragment manager instance
- Returns
true if there is fragment to pop
-
void
lv_fragment_manager_replace(lv_fragment_manager_t *manager, lv_fragment_t *fragment, lv_obj_t *const *container)¶ Replace fragment. Old item in the stack will be removed.
- Parameters
manager -- Fragment manager instance
fragment -- Fragment instance
container -- Pointer to container object for manager to add objects to
-
bool
lv_fragment_manager_send_event(lv_fragment_manager_t *manager, int code, void *userdata)¶ Send event to top-most fragment
- Parameters
manager -- Fragment manager instance
code -- User-defined ID of event
userdata -- User-defined data
- Returns
true if fragment returned true
-
size_t
lv_fragment_manager_get_stack_size(lv_fragment_manager_t *manager)¶ Get stack size of this fragment manager
- Parameters
manager -- Fragment manager instance
- Returns
Stack size of this fragment manager
-
lv_fragment_t *
lv_fragment_manager_get_top(lv_fragment_manager_t *manager)¶ Get top most fragment instance
- Parameters
manager -- Fragment manager instance
- Returns
Top most fragment instance
-
lv_fragment_t *
lv_fragment_manager_find_by_container(lv_fragment_manager_t *manager, const lv_obj_t *container)¶ Find first fragment instance in the container
- Parameters
manager -- Fragment manager instance
container -- Container which target fragment added to
- Returns
First fragment instance in the container
-
lv_fragment_t *
lv_fragment_manager_get_parent_fragment(lv_fragment_manager_t *manager)¶ Get parent fragment
- Parameters
manager -- Fragment manager instance
- Returns
Parent fragment instance
-
lv_fragment_t *
lv_fragment_create(const lv_fragment_class_t *cls, void *args)¶ Create a fragment instance.
- Parameters
cls -- Fragment class. This fragment must return non null object.
args -- Arguments assigned by fragment manager
- Returns
Fragment instance
-
void
lv_fragment_del(lv_fragment_t *fragment)¶ Destroy a fragment.
- Parameters
fragment -- Fragment instance.
-
lv_fragment_manager_t *
lv_fragment_get_manager(lv_fragment_t *fragment)¶ Get associated manager of this fragment
- Parameters
fragment -- Fragment instance
- Returns
Fragment manager instance
-
lv_obj_t *const *
lv_fragment_get_container(lv_fragment_t *fragment)¶ Get container object of this fragment
- Parameters
fragment -- Fragment instance
- Returns
Reference to container object
-
lv_fragment_t *
lv_fragment_get_parent(lv_fragment_t *fragment)¶ Get parent fragment of this fragment
- Parameters
fragment -- Fragment instance
- Returns
Parent fragment
-
lv_obj_t *
lv_fragment_create_obj(lv_fragment_t *fragment, lv_obj_t *container)¶ Create object by fragment.
- Parameters
fragment -- Fragment instance.
container -- Container of the objects should be created upon.
- Returns
Created object
-
void
lv_fragment_del_obj(lv_fragment_t *fragment)¶ Delete created object of a fragment
- Parameters
fragment -- Fragment instance.
-
void
lv_fragment_recreate_obj(lv_fragment_t *fragment)¶ Destroy obj in fragment, and recreate them.
- Parameters
fragment -- Fragment instance
-
struct
_lv_fragment_t¶ Public Members
-
const lv_fragment_class_t *
cls¶ Class of this fragment
-
lv_fragment_managed_states_t *
managed¶ Managed fragment states. If not null, then this fragment is managed.
Warning
Don't modify values inside this struct!
-
lv_fragment_manager_t *
child_manager¶ Child fragment manager
-
const lv_fragment_class_t *
-
struct
_lv_fragment_class_t¶ Public Members
-
void (*
constructor_cb)(lv_fragment_t *self, void *args)¶ Constructor function for fragment class
- Parameters
self -- Fragment instance
args -- Arguments assigned by fragment manager
-
void (*
destructor_cb)(lv_fragment_t *self)¶ Destructor function for fragment class
- Parameters
self -- Fragment instance, will be freed after this call
-
void (*
attached_cb)(lv_fragment_t *self)¶ Fragment attached to manager
- Parameters
self -- Fragment instance
-
void (*
detached_cb)(lv_fragment_t *self)¶ Fragment detached from manager
- Parameters
self -- Fragment instance
-
lv_obj_t *(*
create_obj_cb)(lv_fragment_t *self, lv_obj_t *container)¶ Create objects
- Parameters
self -- Fragment instance
container -- Container of the objects should be created upon
- Returns
Created object, NULL if multiple objects has been created
-
void (*
obj_created_cb)(lv_fragment_t *self, lv_obj_t *obj)¶ - Parameters
self -- Fragment instance
obj -- lv_obj returned by create_obj_cb
-
void (*
obj_will_delete_cb)(lv_fragment_t *self, lv_obj_t *obj)¶ Called before objects in the fragment will be deleted.
- Parameters
self -- Fragment instance
obj -- object with this fragment
-
void (*
obj_deleted_cb)(lv_fragment_t *self, lv_obj_t *obj)¶ Called when the object created by fragment received
LV_EVENT_DELETEevent- Parameters
self -- Fragment instance
obj -- object with this fragment
-
bool (*
event_cb)(lv_fragment_t *self, int code, void *userdata)¶ Handle event
- Parameters
self -- Fragment instance
which -- User-defined ID of event
data1 -- User-defined data
data2 -- User-defined data
-
size_t
instance_size¶ REQUIRED: Allocation size of fragment
-
void (*
-
struct
_lv_fragment_managed_states_t¶ - #include <lv_fragment.h>
Fragment states
Public Members
-
const lv_fragment_class_t *
cls¶ Class of the fragment
-
lv_fragment_manager_t *
manager¶ Manager the fragment attached to
-
lv_fragment_t *
instance¶ Fragment instance
-
bool
obj_created¶ true between
create_obj_cbandobj_deleted_cb
-
bool
destroying_obj¶ true before
lv_fragment_del_objis called. Don't touch any object if this is true
-
bool
in_stack¶ true if this fragment is in navigation stack that can be popped
-
const lv_fragment_class_t *