本文使用LVGL v8.3实现一个密码输入界面
一、宏定义和全局变量
#define PWDLENGTH 4 // 密码位数
#define PWD 6666 // 密码
#define LV_EVENT_BACK 66 // 返回按键的事件通知
static lv_obj_t *PWDInputPage = NULL, *inputTextarea = NULL,
*inputNumKey = NULL, *parentPage = NULL;
// 键盘的键值,需要字母和符号的可以自行添加
static const char *numKeyMap[] = {
"9","8","7","6","\n",
"5","4","3","2","\n",
"1","0",LV_SYMBOL_OK, LV_SYMBOL_BACKSPACE ,""
};
二、基本函数实现
1.首先创建一个整屏大小的显示区域:
PWDInputPage = lv_obj_create(lv_scr_act());
lv_obj_clear_flag(PWDInputPage, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(PWDInputPage, LV_HOR_RES, LV_VER_RES);
lv_obj_set_style_bg_opa(PWDInputPage, LV_OPA_0, 0);
lv_obj_set_style_border_side(PWDInputPage, LV_BORDER_SIDE_NONE, 0);
lv_obj_set_style_radius(PWDInputPage, 0, 0);
创建整张屏幕大小,是因为防止在输入密码时误触到其他地方,导致一些奇奇怪怪的问题。
2.创建密码输入的真实区域,后面的组件都是以这个区域为父组件的:
lv_obj_t *centerCont = lv_obj_create(PWDInputPage);
lv_obj_clear_flag(centerCont, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(centerCont, LV_HOR_RES, LV_VER_RES);
lv_obj_set_size(centerCont, 380, 235);
lv_obj_set_style_radius(centerCont, 5, 0);
lv_obj_set_style_border_side(centerCont, LV_BORDER_SIDE_NONE, 0);
lv_obj_set_style_bg_color(centerCont, lv_color_hex(0xebebeb), 0);
lv_obj_align(centerCont, LV_ALIGN_CENTER, 0, 10);
lv_obj_clear_flag(centerCont, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_event_cb(centerCont, PassWordInputPageEventCbk, LV_EVENT_ALL, NULL); // 此处添加一个回调函数,方便实现页面的管理
3.其他组件创建
// 提示标签
lv_obj_t *tipLabel = lv_label_create(centerCont);
lv_obj_set_pos(tipLabel, 5, -5);
lv_label_set_text_static(tipLabel, "Please input the password");
// 用于存放关闭按钮的容器
lv_obj_t* closeBtnCont = lv_obj_create(centerCont);
lv_obj_clear_flag(closeBtnCont, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(closeBtnCont, 30, 30);
lv_obj_align(closeBtnCont, LV_ALIGN_TOP_RIGHT, 10, -10);
lv_obj_set_style_bg_opa(closeBtnCont, 128, 0);
lv_obj_add_event_cb(closeBtnCont, PassWordInputPageEventCbk, LV_EVENT_ALL, NULL);
// 关闭按钮
lv_obj_t* closeLabel = lv_label_create(closeBtnCont);
lv_obj_set_style_text_color(closeLabel, lv_color_hex(0x000000), 0);
lv_label_set_text_static(closeLabel, LV_SYMBOL_CLOSE);
lv_obj_align(closeLabel, LV_ALIGN_CENTER, 0, 0);
// 放在提示信息下面的横线,为了美观放的,可以忽略...
static lv_point_t linePoints[2] = { {5, 15}, {200, 15} };
lv_obj_t *line = lv_line_create(centerCont);
lv_obj_add_style(line, &lineStyle, 0);
lv_line_set_points(line, linePoints, 2);
// 输入区域
inputTextarea = lv_textarea_create(centerCont);
lv_obj_set_width(inputTextarea, 305);
lv_obj_align(inputTextarea, LV_ALIGN_TOP_MID, 0, 38);
lv_textarea_set_max_length(inputTextarea, 4);
lv_textarea_set_one_line(inputTextarea, true);
lv_textarea_set_password_mode(inputTextarea, true); // 设置为密码输入模式,输入变成****
// 创建一个键盘
inputNumKey = lv_btnmatrix_create(centerCont);
lv_obj_set_size(inputNumKey, 315, 145);
lv_obj_align(inputNumKey, LV_ALIGN_TOP_MID, 0, 73);
lv_obj_set_style_bg_opa(inputNumKey, LV_OPA_0, 0);
lv_obj_set_style_border_side(inputNumKey, LV_BORDER_SIDE_NONE, 0);
lv_btnmatrix_set_map(inputNumKey, numKeyMap);
lv_obj_set_style_pad_row(inputNumKey, 15, 0);
lv_obj_set_style_pad_column(inputNumKey, 15, 0);
lv_btnmatrix_set_btn_ctrl_all(inputNumKey, LV_BTNMATRIX_CTRL_CLICK_TRIG);
lv_obj_add_event_cb(inputNumKey, PWDNumKeyEventCbk, LV_EVENT_ALL, NULL);
至此,一个大致的界面就创建好了,下面是一个效果图:
三、回调函数实现:
1.整个界面的回调函数,用于管理界面
static void PassWordInputPageEventCbk(lv_event_t *event)
{
lv_event_code_t code = lv_event_get_code(event);
lv_obj_t *obj = event->current_target;
if (code == LV_EVENT_BACK)
{
// 删除当前界面,设置上一个界面为活动界面
lv_obj_del(PWDInputPage);
SetCurrentWindow(parentPage);
}
}
2.输入按键的回调函数,判断密码是否正确
static void PWDNumKeyEventCbk(lv_event_t *event)
{
lv_event_code_t code = lv_event_get_code(event);
lv_obj_t *obj = event->current_target;
if (code == LV_EVENT_VALUE_CHANGED)
{
u16 keyIndex = lv_btnmatrix_get_selected_btn(inputNumKey);
if (keyIndex < 10)
{
InputNumCnt++;
if (InputNumCnt >= PWDLENGTH)
{
InputNumCnt = PWDLENGTH;
}
lv_textarea_add_char(inputNumKey, *lv_btnmatrix_get_btn_text(inputNumKey, keyIndex));
}
else if (keyIndex == 10)
{
char *str = (char *)lv_textarea_get_text(inputNumKey);
u32 pwd = atol(str);
if (pwd == 6666 && InputNumCnt == PWDLENGTH)
{
// 正确处理
lv_obj_del(PWDInputPage);
}
else
{
// 错误处理
}
}
else
{
InputNumCnt--;
if (InputNumCnt <= 0)
{
InputNumCnt = 0;
}
lv_textarea_del_char(inputNumKey);
}
}
}
至此,一个密码输入和验证界面就完成了。