UI基础_hitTest扩大响应范围

本文介绍如何通过重写hitTest:withEvent:方法来调整UIButton和UISlider的响应范围,包括如何判断触摸点的位置以及实现代码示例。

在需要扩大和缩小UIButton/UISlider的响应范围时,重写 hitTest方法

hitTest:withEvent:方法的使用:

1.首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内;
2.若返回NO,则hitTest:withEvent:返回nil;
3.若返回YES,则向当前视图的所有子视图(subviews)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从top到bottom,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕;
4.若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束;
5.如所有子视图都返回非,则hitTest:withEvent:方法返回自身(self)。
  • 注:hitTest:withEvent:方法忽略隐藏(hidden=YES)的视图,禁止用户操作(userInteractionEnabled=YES)的视图,以及alpha级别小于0.01(alpha<0.01)的视图。
//扩大slider的响应范围
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (CGRectContainsPoint(CGRectInset(self.bounds, -20, -20), point) &&!CGRectContainsPoint(self.textView.frame, point)){
        return self.slider;
    }
    return [super hitTest:point withEvent:event];
}

判断触摸点是否在某个范围上

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return YES;
}
void ui_Menu_screen_init(void) { current_screen_set(SCREEN_MENU); ui_Menu = lv_obj_create(NULL); lv_obj_clear_flag(ui_Menu, LV_OBJ_FLAG_SCROLLABLE); /// Flags ui_menuPanel = lv_obj_create(ui_Menu); lv_obj_set_width(ui_menuPanel, lv_pct(100)); lv_obj_set_height(ui_menuPanel, lv_pct(71)); lv_obj_set_x(ui_menuPanel, 0); lv_obj_set_y(ui_menuPanel, 29); lv_obj_set_align(ui_menuPanel, LV_ALIGN_CENTER); lv_obj_set_flex_flow(ui_menuPanel, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(ui_menuPanel, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); lv_obj_set_style_radius(ui_menuPanel, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_side(ui_menuPanel, LV_BORDER_SIDE_NONE, LV_PART_MAIN | LV_STATE_DEFAULT); ui_menuDAPLINKB = lv_btn_create(ui_menuPanel); lv_obj_set_height(ui_menuDAPLINKB, 40); lv_obj_set_width(ui_menuDAPLINKB, lv_pct(100)); lv_obj_set_align(ui_menuDAPLINKB, LV_ALIGN_CENTER); lv_obj_add_flag(ui_menuDAPLINKB, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags lv_obj_clear_flag(ui_menuDAPLINKB, LV_OBJ_FLAG_SCROLLABLE); /// Flags lv_obj_set_style_text_align(ui_menuDAPLINKB, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_menuDAPLINKB, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_color(ui_menuDAPLINKB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_opa(ui_menuDAPLINKB, 255, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_width(ui_menuDAPLINKB, 2, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_pad(ui_menuDAPLINKB, 0, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_color(ui_menuDAPLINKB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_opa(ui_menuDAPLINKB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_width(ui_menuDAPLINKB, 2, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_pad(ui_menuDAPLINKB, 0, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_color(ui_menuDAPLINKB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_opa(ui_menuDAPLINKB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); ui_menuDAPLINKL = lv_label_create(ui_menuDAPLINKB); lv_obj_set_width(ui_menuDAPLINKL, LV_SIZE_CONTENT); /// 1 lv_obj_set_height(ui_menuDAPLINKL, LV_SIZE_CONTENT); /// 1 lv_obj_set_align(ui_menuDAPLINKL, LV_ALIGN_CENTER); lv_label_set_text(ui_menuDAPLINKL, "在线DAPLINK"); ui_menuOfflineB = lv_btn_create(ui_menuPanel); lv_obj_set_height(ui_menuOfflineB, 40); lv_obj_set_width(ui_menuOfflineB, lv_pct(100)); lv_obj_set_align(ui_menuOfflineB, LV_ALIGN_CENTER); lv_obj_add_flag(ui_menuOfflineB, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags lv_obj_clear_flag(ui_menuOfflineB, LV_OBJ_FLAG_SCROLLABLE); /// Flags lv_obj_set_style_text_align(ui_menuOfflineB, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_menuOfflineB, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_color(ui_menuOfflineB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_opa(ui_menuOfflineB, 255, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_width(ui_menuOfflineB, 2, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_pad(ui_menuOfflineB, 0, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_color(ui_menuOfflineB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_opa(ui_menuOfflineB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_width(ui_menuOfflineB, 2, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_pad(ui_menuOfflineB, 0, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_color(ui_menuOfflineB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_opa(ui_menuOfflineB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); ui_menuOfflineL = lv_label_create(ui_menuOfflineB); lv_obj_set_width(ui_menuOfflineL, LV_SIZE_CONTENT); /// 1 lv_obj_set_height(ui_menuOfflineL, LV_SIZE_CONTENT); /// 1 lv_obj_set_align(ui_menuOfflineL, LV_ALIGN_CENTER); lv_label_set_text(ui_menuOfflineL, "脱机烧录器"); ui_menuAmmeterB = lv_btn_create(ui_menuPanel); lv_obj_set_height(ui_menuAmmeterB, 40); lv_obj_set_width(ui_menuAmmeterB, lv_pct(100)); lv_obj_set_align(ui_menuAmmeterB, LV_ALIGN_CENTER); lv_obj_add_flag(ui_menuAmmeterB, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags lv_obj_clear_flag(ui_menuAmmeterB, LV_OBJ_FLAG_SCROLLABLE); /// Flags lv_obj_set_style_text_align(ui_menuAmmeterB, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_menuAmmeterB, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_color(ui_menuAmmeterB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_opa(ui_menuAmmeterB, 255, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_width(ui_menuAmmeterB, 2, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_pad(ui_menuAmmeterB, 0, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_color(ui_menuAmmeterB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_opa(ui_menuAmmeterB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_width(ui_menuAmmeterB, 2, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_pad(ui_menuAmmeterB, 0, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_color(ui_menuAmmeterB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_opa(ui_menuAmmeterB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); ui_menuAmmeterL = lv_label_create(ui_menuAmmeterB); lv_obj_set_width(ui_menuAmmeterL, LV_SIZE_CONTENT); /// 1 lv_obj_set_height(ui_menuAmmeterL, LV_SIZE_CONTENT); /// 1 lv_obj_set_align(ui_menuAmmeterL, LV_ALIGN_CENTER); lv_label_set_text(ui_menuAmmeterL, "电压电流输出"); ui_menuUARTB = lv_btn_create(ui_menuPanel); lv_obj_set_height(ui_menuUARTB, 40); lv_obj_set_width(ui_menuUARTB, lv_pct(100)); lv_obj_set_align(ui_menuUARTB, LV_ALIGN_CENTER); lv_obj_add_flag(ui_menuUARTB, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags lv_obj_clear_flag(ui_menuUARTB, LV_OBJ_FLAG_SCROLLABLE); /// Flags lv_obj_set_style_text_align(ui_menuUARTB, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_menuUARTB, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_color(ui_menuUARTB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_opa(ui_menuUARTB, 255, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_width(ui_menuUARTB, 2, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_pad(ui_menuUARTB, 0, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_color(ui_menuUARTB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_opa(ui_menuUARTB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_width(ui_menuUARTB, 2, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_pad(ui_menuUARTB, 0, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_color(ui_menuUARTB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_opa(ui_menuUARTB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); ui_menuUARTL = lv_label_create(ui_menuUARTB); lv_obj_set_width(ui_menuUARTL, LV_SIZE_CONTENT); /// 1 lv_obj_set_height(ui_menuUARTL, LV_SIZE_CONTENT); /// 1 lv_obj_set_align(ui_menuUARTL, LV_ALIGN_CENTER); lv_label_set_text(ui_menuUARTL, "串口监视器"); ui_menuPWMB = lv_btn_create(ui_menuPanel); lv_obj_set_height(ui_menuPWMB, 40); lv_obj_set_width(ui_menuPWMB, lv_pct(100)); lv_obj_set_align(ui_menuPWMB, LV_ALIGN_CENTER); lv_obj_add_flag(ui_menuPWMB, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags lv_obj_clear_flag(ui_menuPWMB, LV_OBJ_FLAG_SCROLLABLE); /// Flags lv_obj_set_style_text_align(ui_menuPWMB, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_menuPWMB, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_color(ui_menuPWMB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_opa(ui_menuPWMB, 255, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_width(ui_menuPWMB, 2, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_pad(ui_menuPWMB, 0, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_color(ui_menuPWMB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_opa(ui_menuPWMB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_width(ui_menuPWMB, 2, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_pad(ui_menuPWMB, 0, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_color(ui_menuPWMB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_opa(ui_menuPWMB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); ui_menuPWML = lv_label_create(ui_menuPWMB); lv_obj_set_width(ui_menuPWML, LV_SIZE_CONTENT); /// 1 lv_obj_set_height(ui_menuPWML, LV_SIZE_CONTENT); /// 1 lv_obj_set_align(ui_menuPWML, LV_ALIGN_CENTER); lv_label_set_text(ui_menuPWML, "PWM输出"); ui_menuDACOutputB = lv_btn_create(ui_menuPanel); lv_obj_set_height(ui_menuDACOutputB, 40); lv_obj_set_width(ui_menuDACOutputB, lv_pct(100)); lv_obj_set_align(ui_menuDACOutputB, LV_ALIGN_CENTER); lv_obj_add_flag(ui_menuDACOutputB, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags lv_obj_clear_flag(ui_menuDACOutputB, LV_OBJ_FLAG_SCROLLABLE); /// Flags lv_obj_set_style_text_align(ui_menuDACOutputB, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_menuDACOutputB, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_color(ui_menuDACOutputB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_opa(ui_menuDACOutputB, 255, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_width(ui_menuDACOutputB, 2, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_pad(ui_menuDACOutputB, 0, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_color(ui_menuDACOutputB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_opa(ui_menuDACOutputB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_width(ui_menuDACOutputB, 2, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_pad(ui_menuDACOutputB, 0, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_color(ui_menuDACOutputB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_opa(ui_menuDACOutputB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); ui_menuDACOutputL = lv_label_create(ui_menuDACOutputB); lv_obj_set_width(ui_menuDACOutputL, LV_SIZE_CONTENT); /// 1 lv_obj_set_height(ui_menuDACOutputL, LV_SIZE_CONTENT); /// 1 lv_obj_set_align(ui_menuDACOutputL, LV_ALIGN_CENTER); lv_label_set_text(ui_menuDACOutputL, "DAC输出"); ui_menuSDCardB = lv_btn_create(ui_menuPanel); lv_obj_set_height(ui_menuSDCardB, 40); lv_obj_set_width(ui_menuSDCardB, lv_pct(100)); lv_obj_set_align(ui_menuSDCardB, LV_ALIGN_CENTER); lv_obj_add_flag(ui_menuSDCardB, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags lv_obj_clear_flag(ui_menuSDCardB, LV_OBJ_FLAG_SCROLLABLE); /// Flags lv_obj_set_style_text_align(ui_menuSDCardB, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_menuSDCardB, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_color(ui_menuSDCardB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_opa(ui_menuSDCardB, 255, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_width(ui_menuSDCardB, 2, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_pad(ui_menuSDCardB, 0, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_color(ui_menuSDCardB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_opa(ui_menuSDCardB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_width(ui_menuSDCardB, 2, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_pad(ui_menuSDCardB, 0, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_color(ui_menuSDCardB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_opa(ui_menuSDCardB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); ui_menuSDCardL = lv_label_create(ui_menuSDCardB); lv_obj_set_width(ui_menuSDCardL, LV_SIZE_CONTENT); /// 1 lv_obj_set_height(ui_menuSDCardL, LV_SIZE_CONTENT); /// 1 lv_obj_set_align(ui_menuSDCardL, LV_ALIGN_CENTER); lv_label_set_text(ui_menuSDCardL, "文件浏览器"); ui_logoAndTextContainer2 = lv_obj_create(ui_Menu); lv_obj_remove_style_all(ui_logoAndTextContainer2); lv_obj_set_height(ui_logoAndTextContainer2, 57); lv_obj_set_width(ui_logoAndTextContainer2, lv_pct(98)); lv_obj_set_x(ui_logoAndTextContainer2, 0); lv_obj_set_y(ui_logoAndTextContainer2, 5); lv_obj_set_align(ui_logoAndTextContainer2, LV_ALIGN_TOP_MID); lv_obj_clear_flag(ui_logoAndTextContainer2, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE); /// Flags ui_LogoLite2 = lv_img_create(ui_logoAndTextContainer2); lv_img_set_src(ui_LogoLite2, &ui_img_743788411); lv_obj_set_width(ui_LogoLite2, LV_SIZE_CONTENT); /// 79 lv_obj_set_height(ui_LogoLite2, LV_SIZE_CONTENT); /// 57 lv_obj_set_align(ui_LogoLite2, LV_ALIGN_LEFT_MID); lv_obj_add_flag(ui_LogoLite2, LV_OBJ_FLAG_ADV_HITTEST); /// Flags lv_obj_clear_flag(ui_LogoLite2, LV_OBJ_FLAG_SCROLLABLE); /// Flags ui_LogoTitle2 = lv_label_create(ui_logoAndTextContainer2); lv_obj_set_width(ui_LogoTitle2, LV_SIZE_CONTENT); /// 1 lv_obj_set_height(ui_LogoTitle2, LV_SIZE_CONTENT); /// 1 lv_obj_set_x(ui_LogoTitle2, -4); lv_obj_set_y(ui_LogoTitle2, 0); lv_obj_set_align(ui_LogoTitle2, LV_ALIGN_TOP_RIGHT); lv_label_set_text(ui_LogoTitle2, "立创开发板"); lv_obj_set_style_text_color(ui_LogoTitle2, lv_color_hex(0x0091E6), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_LogoTitle2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_LogoTitle2, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); ui_LogoWebsite2 = lv_label_create(ui_logoAndTextContainer2); lv_obj_set_width(ui_LogoWebsite2, LV_SIZE_CONTENT); /// 1 lv_obj_set_height(ui_LogoWebsite2, LV_SIZE_CONTENT); /// 1 lv_obj_set_x(ui_LogoWebsite2, -13); lv_obj_set_y(ui_LogoWebsite2, -2); lv_obj_set_align(ui_LogoWebsite2, LV_ALIGN_BOTTOM_RIGHT); lv_label_set_text(ui_LogoWebsite2, "WWW.LCKFB.COM"); lv_obj_set_style_text_color(ui_LogoWebsite2, lv_color_hex(0x0091E6), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_LogoWebsite2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_LogoWebsite2, &ui_font_jetbrainsMonoMedium16, LV_PART_MAIN | LV_STATE_DEFAULT); ui_menuAboutB = lv_btn_create(ui_menuPanel); lv_obj_set_height(ui_menuAboutB, 40); lv_obj_set_width(ui_menuAboutB, lv_pct(100)); lv_obj_set_align(ui_menuAboutB, LV_ALIGN_CENTER); lv_obj_add_flag(ui_menuAboutB, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags lv_obj_clear_flag(ui_menuAboutB, LV_OBJ_FLAG_SCROLLABLE); /// Flags lv_obj_set_style_text_align(ui_menuAboutB, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_menuAboutB, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_color(ui_menuAboutB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_opa(ui_menuAboutB, 255, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_width(ui_menuAboutB, 2, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_pad(ui_menuAboutB, 0, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_color(ui_menuAboutB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_opa(ui_menuAboutB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_width(ui_menuAboutB, 2, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_pad(ui_menuAboutB, 0, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_color(ui_menuAboutB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_opa(ui_menuAboutB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); ui_menuAboutL = lv_label_create(ui_menuAboutB); lv_obj_set_width(ui_menuAboutL, LV_SIZE_CONTENT); /// 1 lv_obj_set_height(ui_menuAboutL, LV_SIZE_CONTENT); /// 1 lv_obj_set_align(ui_menuAboutL, LV_ALIGN_CENTER); lv_label_set_text(ui_menuAboutL, "关于"); lv_obj_add_event_cb(ui_menuDAPLINKB, ui_event_menuDAPLINKB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuOfflineB, ui_event_menuOfflineB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuAmmeterB, ui_event_menuAmmeterB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuUARTB, ui_event_menuUARTB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuPWMB, ui_event_menuPWMB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuDACOutputB, ui_event_menuDACOutputB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuSDCardB, ui_event_menuSDCardB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuAboutB, ui_event_menuAboutB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_Menu, ui_event_Menu, LV_EVENT_ALL, NULL); }
最新发布
11-01
```c void ui_Menu_screen_init(void) { // 设置当前屏幕状态为 MENU 屏幕 current_screen_set(SCREEN_MENU); // 创建主菜单屏幕对象(根容器) ui_Menu = lv_obj_create(NULL); // 禁用滚动功能(确保整个页面不可滚动) lv_obj_clear_flag(ui_Menu, LV_OBJ_FLAG_SCROLLABLE); // 创建菜单面板容器,用于放置所有按钮 ui_menuPanel = lv_obj_create(ui_Menu); lv_obj_set_width(ui_menuPanel, lv_pct(100)); // 宽度占父容器的 100% lv_obj_set_height(ui_menuPanel, lv_pct(71)); // 高度占父容器的 71% lv_obj_set_x(ui_menuPanel, 0); // X 坐标偏移为 0 lv_obj_set_y(ui_menuPanel, 29); // Y 坐标向下偏移 29px lv_obj_set_align(ui_menuPanel, LV_ALIGN_CENTER); // 对齐方式:居中对齐 lv_obj_set_flex_flow(ui_menuPanel, LV_FLEX_FLOW_COLUMN); // 使用纵向 Flex 布局排列子元素 lv_obj_set_flex_align(ui_menuPanel, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); // 主轴、交叉轴和换行线都靠前对齐 // 移除圆角和边框样式 lv_obj_set_style_radius(ui_menuPanel, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_side(ui_menuPanel, LV_BORDER_SIDE_NONE, LV_PART_MAIN | LV_STATE_DEFAULT); // 创建多个按钮及其标签,并设置统一风格 ui_menuDAPLINKB = lv_btn_create(ui_menuPanel); lv_obj_set_height(ui_menuDAPLINKB, 40); // 按钮高度 40px lv_obj_set_width(ui_menuDAPLINKB, lv_pct(100)); // 宽度占满父容器 lv_obj_set_align(ui_menuDAPLINKB, LV_ALIGN_CENTER); // 内容居中 lv_obj_add_flag(ui_menuDAPLINKB, LV_OBJ_FLAG_SCROLL_ON_FOCUS);// 获得焦点时允许滚动 lv_obj_clear_flag(ui_menuDAPLINKB, LV_OBJ_FLAG_SCROLLABLE); // 自身不可滚动 lv_obj_set_style_text_align(ui_menuDAPLINKB, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); // 文本居中 lv_obj_set_style_text_font(ui_menuDAPLINKB, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); // 设置字体 // 设置聚焦状态下的外框样式(黑色,宽度2px) lv_obj_set_style_outline_color(ui_menuDAPLINKB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_opa(ui_menuDAPLINKB, 255, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_width(ui_menuDAPLINKB, 2, LV_PART_MAIN | LV_STATE_FOCUSED); lv_obj_set_style_outline_pad(ui_menuDAPLINKB, 0, LV_PART_MAIN | LV_STATE_FOCUSED); // 同样设置 FOCUS_KEY 状态的样式(键盘导航等场景使用) lv_obj_set_style_outline_color(ui_menuDAPLINKB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_opa(ui_menuDAPLINKB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_width(ui_menuDAPLINKB, 2, LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_outline_pad(ui_menuDAPLINKB, 0, LV_PART_MAIN | LV_STATE_FOCUS_KEY); // 设置文本颜色在 FOCUS_KEY 状态下也为黑色 lv_obj_set_style_text_color(ui_menuDAPLINKB, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_FOCUS_KEY); lv_obj_set_style_text_opa(ui_menuDAPLINKB, 255, LV_PART_MAIN | LV_STATE_FOCUS_KEY); // 在按钮上创建标签并设置文本 ui_menuDAPLINKL = lv_label_create(ui_menuDAPLINKB); lv_obj_set_width(ui_menuDAPLINKL, LV_SIZE_CONTENT); lv_obj_set_height(ui_menuDAPLINKL, LV_SIZE_CONTENT); lv_obj_set_align(ui_menuDAPLINKL, LV_ALIGN_CENTER); lv_label_set_text(ui_menuDAPLINKL, "在线DAPLINK"); // 重复以上过程创建其他按钮:脱机烧录器、电压电流输出、串口监视器、PWM输出、DAC输出、文件浏览器、关于 // (以下省略详细注释,结构与上面一致) ui_menuOfflineB = lv_btn_create(ui_menuPanel); lv_obj_set_height(ui_menuOfflineB, 40); lv_obj_set_width(ui_menuOfflineB, lv_pct(100)); lv_obj_set_align(ui_menuOfflineB, LV_ALIGN_CENTER); lv_obj_add_flag(ui_menuOfflineB, LV_OBJ_FLAG_SCROLL_ON_FOCUS); lv_obj_clear_flag(ui_menuOfflineB, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_text_align(ui_menuOfflineB, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_menuOfflineB, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); // ... 样式设置同上 ... ui_menuOfflineL = lv_label_create(ui_menuOfflineB); lv_label_set_text(ui_menuOfflineL, "脱机烧录器"); // 类似地创建其余按钮: ui_menuAmmeterB = lv_btn_create(ui_menuPanel); lv_label_set_text(lv_label_create(ui_menuAmmeterB), "电压电流输出"); // ... 设置相同样式 ... ui_menuUARTB = lv_btn_create(ui_menuPanel); lv_label_set_text(lv_label_create(ui_menuUARTB), "串口监视器"); ui_menuPWMB = lv_btn_create(ui_menuPanel); lv_label_set_text(lv_label_create(ui_menuPWMB), "PWM输出"); ui_menuDACOutputB = lv_btn_create(ui_menuPanel); lv_label_set_text(lv_label_create(ui_menuDACOutputB), "DAC输出"); ui_menuSDCardB = lv_btn_create(ui_menuPanel); lv_label_set_text(lv_label_create(ui_menuSDCardB), "文件浏览器"); ui_menuAboutB = lv_btn_create(ui_menuPanel); lv_label_set_text(lv_label_create(ui_menuAboutB), "关于"); // 创建顶部 Logo 和文字容器 ui_logoAndTextContainer2 = lv_obj_create(ui_Menu); lv_obj_remove_style_all(ui_logoAndTextContainer2); // 清除所有默认样式 lv_obj_set_height(ui_logoAndTextContainer2, 57); lv_obj_set_width(ui_logoAndTextContainer2, lv_pct(98)); // 宽度为父容器的 98% lv_obj_set_x(ui_logoAndTextContainer2, 0); lv_obj_set_y(ui_logoAndTextContainer2, 5); lv_obj_set_align(ui_logoAndTextContainer2, LV_ALIGN_TOP_MID); // 顶部居中对齐 lv_obj_clear_flag(ui_logoAndTextContainer2, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE); // 添加 Logo 图片 ui_LogoLite2 = lv_img_create(ui_logoAndTextContainer2); lv_img_set_src(ui_LogoLite2, &ui_img_743788411); // 加载图片资源 lv_obj_set_width(ui_LogoLite2, LV_SIZE_CONTENT); lv_obj_set_height(ui_LogoLite2, LV_SIZE_CONTENT); lv_obj_set_align(ui_LogoLite2, LV_ALIGN_LEFT_MID); // 左中对齐 lv_obj_add_flag(ui_LogoLite2, LV_OBJ_FLAG_ADV_HITTEST); // 启用高级点击检测 lv_obj_clear_flag(ui_LogoLite2, LV_OBJ_FLAG_SCROLLABLE); // 添加标题文本:“立创开发板” ui_LogoTitle2 = lv_label_create(ui_logoAndTextContainer2); lv_obj_set_width(ui_LogoTitle2, LV_SIZE_CONTENT); lv_obj_set_height(ui_LogoTitle2, LV_SIZE_CONTENT); lv_obj_set_x(ui_LogoTitle2, -4); lv_obj_set_y(ui_LogoTitle2, 0); lv_obj_set_align(ui_LogoTitle2, LV_ALIGN_TOP_RIGHT); lv_label_set_text(ui_LogoTitle2, "立创开发板"); lv_obj_set_style_text_color(ui_LogoTitle2, lv_color_hex(0x0091E6), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_LogoTitle2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_LogoTitle2, &ui_font_PuHuiTi30, LV_PART_MAIN | LV_STATE_DEFAULT); // 添加网站链接文本 ui_LogoWebsite2 = lv_label_create(ui_logoAndTextContainer2); lv_obj_set_width(ui_LogoWebsite2, LV_SIZE_CONTENT); lv_obj_set_height(ui_LogoWebsite2, LV_SIZE_CONTENT); lv_obj_set_x(ui_LogoWebsite2, -13); lv_obj_set_y(ui_LogoWebsite2, -2); lv_obj_set_align(ui_LogoWebsite2, LV_ALIGN_BOTTOM_RIGHT); lv_label_set_text(ui_LogoWebsite2, "WWW.LCKFB.COM"); lv_obj_set_style_text_color(ui_LogoWebsite2, lv_color_hex(0x0091E6), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_LogoWebsite2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_LogoWebsite2, &ui_font_jetbrainsMonoMedium16, LV_PART_MAIN | LV_STATE_DEFAULT); // 为每个按钮注册事件回调函数 lv_obj_add_event_cb(ui_menuDAPLINKB, ui_event_menuDAPLINKB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuOfflineB, ui_event_menuOfflineB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuAmmeterB, ui_event_menuAmmeterB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuUARTB, ui_event_menuUARTB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuPWMB, ui_event_menuPWMB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuDACOutputB, ui_event_menuDACOutputB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuSDCardB, ui_event_menuSDCardB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_menuAboutB, ui_event_menuAboutB, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_Menu, ui_event_Menu, LV_EVENT_ALL, NULL); } ``` --- ### ✅ 功能总结: 这个函数 `ui_Menu_screen_init()` 是一个 **LVGL 用户界面初始化函数**,用于构建一个完整的“主菜单”界面。它实现了以下功能: #### 1. **整体结构** - 创建了一个全屏的菜单界面 `ui_Menu`。 - 包含两个主要区域: - 顶部:品牌 Logo + 标题 + 官网地址(`ui_logoAndTextContainer2`) - 中部:垂直排列的功能按钮列表(`ui_menuPanel`) #### 2. **布局系统使用** - 使用了 **Flexbox 布局** (`LV_FLEX_FLOW_COLUMN`) 实现按钮自动纵向排列。 - 所有按钮宽度设为 `lv_pct(100)`,即填满容器宽度。 - 通过 `lv_obj_set_x/y()` 和 `lv_obj_set_align()` 精确控制位置。 #### 3. **UI 元素设计** - 每个功能项是一个按钮(`lv_btn_create`),内部包含一个居中文本标签。 - 所有按钮具有统一的高度(40px)、字体(`PuHuiTi30`)、文本居中等样式。 - 聚焦时显示黑色实线外框(`outline`),提升可访问性(适用于键盘/编码器操作)。 #### 4. **视觉美化** - 顶部容器包含图像和两行文字(品牌名 + 官网),使用右上角对齐实现美观排版。 - 使用自定义字体(如 `&ui_font_PuHuiTi30`)增强视觉体验。 - 使用十六进制颜色 `lv_color_hex(0x0091E6)` 显示蓝色主题色(立创蓝)。 #### 5. **交互支持** - 所有按钮都添加了事件回调(`lv_obj_add_event_cb`),可以响应点击、获得焦点等行为。 - 支持 `SCROLL_ON_FOCUS`,方便在大页面中将焦点元素滚动到可视区域。 --- ### 🧩 技术亮点解析 | 特性 | 说明 | |------|------| | `lv_obj_set_flex_flow(..., LV_FLEX_FLOW_COLUMN)` | 实现垂直流式布局,新增按钮会自动往下排 | | `lv_pct(100)` | 百分比单位,适配不同分辨率屏幕 | | `LV_PART_MAIN \| LV_STATE_FOCUSED` | 为目标状态设置特定样式(如高亮边框) | | `LV_SIZE_CONTENT` | 宽高自适应内容大小 | | `lv_obj_remove_style_all()` | 清除默认样式,便于自定义外观 | | `LV_OBJ_FLAG_ADV_HITTEST` | 启用精确命中测试(例如透明区域不响应触摸) | --- ### ⚠️ 注意事项 - 必须提前定义所有事件回调函数(如 `ui_event_menuDAPLINKB`),否则链接失败。 - 图片资源 `&ui_img_743788411` 需要由 LVGL 图像编码工具生成(如 bin 或 c 文件嵌入)。 - 字体 `&ui_font_PuHuiTi30` 和 `&ui_font_jetbrainsMonoMedium16` 必须已声明并包含在项目中。 --- ### 💡 可优化建议 1. **减少重复代码**: 多个按钮设置完全一致,可用循环或封装函数创建: ```c lv_obj_t * create_menu_button(lv_obj_t * parent, const char * text, lv_event_cb_t cb) { lv_obj_t * btn = lv_btn_create(parent); lv_obj_set_size(btn, lv_pct(100), 40); lv_obj_set_align(btn, LV_ALIGN_CENTER); // ... 公共样式 ... lv_obj_t * label = lv_label_create(btn); lv_label_set_text(label, text); lv_obj_center(label); lv_obj_add_event_cb(btn, cb, LV_EVENT_ALL, NULL); return btn; } ``` 2. **响应式设计改进**: 使用 `lv_pct()` 和 Flex 布局已经很好,但可进一步根据屏幕尺寸动态调整字体大小。 3. **内存优化**: 若按钮过多且不在同一时间可见,可考虑使用 `lv_list` 或滚动容器替代静态创建。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值