本文使用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);

至此,一个大致的界面就创建好了,下面是一个效果图:

用LVGL写一个密码输入验证界面_lvgl

三、回调函数实现:

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);
        }
    }
}

至此,一个密码输入和验证界面就完成了。