AirUI 组件演示
一、概述
本项目是基于 AirUI 图形用户界面库的完整组件演示程序,展示了多种 UI 组件和功能模块。每个演示模块独立运行,通过主程序 main.lua 统一调度管理。
二、演示功能概述
2.1 核心驱动模块
1、main.lua - 主程序入口
-
项目初始化和版本定义
-
系统任务调度和看门狗配置
- 演示模块的选择和加载
2、lcd_drv.lua - LCD 显示驱动
- 初始化 LCD 屏幕及背光
- 配置显示参数和缓冲区
- 初始化 AirUI 框架
3、tp_drv.lua - 触摸面板驱动
- 初始化 GT911 触摸控制器
- 配置 I2C 通信和触摸回调
- 绑定触摸设备到 AirUI 输入系统
2.2 基础组件演示
airui_label.lua- 标签组件演示airui_button.lua- 按钮组件演示airui_image.lua- 图片组件演示airui_container.lua- 容器组件演示airui_bar.lua- (动态)进度条组件演示
2.3 交互组件演示
airui_switch.lua- 开关组件演示airui_dropdown.lua- 下拉框组件演示airui_input.lua- 输入框和虚拟键盘演示airui_msgbox.lua- 消息框组件演示
2.4 布局与高级组件演示
airui_table.lua- 表格组件演示airui_tabview.lua- 选项卡组件演示airui_win.lua- 窗口组件演示airui_switch_page.lua- 多页面切换功能演示airui_all_component.lua- 所有组件综合演示airui_chart.lua- 图表组件演示airui_qrcode.lua- 二维码组件演示
2.5 字体渲染演示
airui_hzfont.lua- HzFont 矢量字体特性演示
三、准备硬件环境

1、Air8101 核心板 × 1
2、AirLCD_1020 触摸配件板 × 1
3、双排40PIN的双头线 x 1
4、TYPE-C 数据线 × 1
5、Air8101 核心板和 AirLCD_1020配件板的硬件接线方式为
- Air8101 核心板通过 TYPE-C USB 口供电(核心板背面的功耗测试开关拨到 OFF 一端,正面开关打到 3.3V 一端),此种供电方式下,vbat 引脚为 3.3V,可以直接给 AirLCD_1020配件板供电;
- 为了演示方便,所以 Air8101 核心板上电后直接通过 vbat 引脚给 AirLCD_1020配件板提供了 3.3V 的供电;
- 客户在设计实际项目时,一般来说,需要通过一个GPIO来控制LDO给LCD和TP供电,这样可以灵活地控制供电,可以使项目的整体功耗降到最低;
-
核心板和配件板之间配备了双排40PIN的双头线,可以参考下表很方便地连接双方各自的40个管脚,插入或者拔出双头线时,要慢慢的操作,防止将排针折弯
-
- 核心板和配件板之间配备了双排40PIN的双头线,可以参考下表很方便地连接双方各自的40个管脚,插入或者拔出双头线时,要慢慢的操作,防止将排针折弯;
5.2 接线配置
5.2.1 显示屏接线
| Air8101核心板 | AirLCD_1020配件板 |
|---|---|
| gnd | GND |
| vbat | VCC |
| 42/R0 | RGB_R0 |
| 40/R1 | RGB_R1 |
| 43/R2 | RGB_R2 |
| 39/R3 | RGB_R3 |
| 44/R4 | RGB_R4 |
| 38/R5 | RGB_R5 |
| 45/R6 | RGB_R6 |
| 37/R7 | RGB_R7 |
| 46/G0 | RGB_G0 |
| 36/G1 | RGB_G1 |
| 47/G2 | RGB_G2 |
| 35/G3 | RGB_G3 |
| 48/G4 | RGB_G4 |
| 34/G5 | RGB_G5 |
| 49/G6 | RGB_G6 |
| 33/G7 | RGB_G7 |
| 50/B0 | RGB_B0 |
| 32/B1 | RGB_B1 |
| 51/B2 | RGB_B2 |
| 31/B3 | RGB_B3 |
| 52/B4 | RGB_B4 |
| 30/B5 | RGB_B5 |
| 53/B6 | RGB_B6 |
| 29/B7 | RGB_B7 |
| 28/DCLK | RGB_DCLK |
| 54/DISP | RGB_DISP |
| 55/HSYN | RGB_HSYNC |
| 56/VSYN | RGB_VSYNC |
| 57/DE | RGB_DE |
| 14/GPIO8 | LCD_BL |
| 13/GPIO9 | LCD_RST |
| 8/GPIO5 | LCD_SDI |
| 9/GPIO6 | LCD_SCL |
| 68/GPIO12 | LCD_CS |
| 75/GPIO28 | TP_RST |
| 10/GPIO7 | TP_INT |
| 12/U1TX | TP_SCL |
| 11/U1RX | TP_SDA |
四、准备软件环境
4.1 软件环境
在开始实践本示例之前,先筹备一下软件环境:
1、烧录工具:Luatools 下载调试工具
2、本demo开发测试时使用的固件为LuatOS-SoC_V2004_Air8101_104.soc,(请使用支持airui功能固件),所以你如果要测试本demo时,可以直接使用最新版本支持airui功能的内核固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;
3、脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air8101/demo/ui/airui/single
4、lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件
准备好软件环境之后,接下来查看如何烧录项目文件到Air8101核心板,将本篇文章中演示使用的项目文件烧录到Air8101核心板中。
4.2 API 介绍
airui-功能强大的图形化开发:https://docs.openluat.com/osapi/core/airui/
五、程序结构
ui/airui/single
│── main.lua
│── images
│── xxx.jpg
│── airui_all_component.lua
│── airui_bar.lua
│── airui_button.lua
│── airui_chart.lua
│── airui_container.lua
│── airui_dropdown.lua
│── airui_hzfont.lua
│── airui_image.lua
│── airui_input.lua
│── airui_label.lua
│── airui_msgbox.lua
│── airui_qrcode.lua
│── airui_switch.lua
│── airui_switch_page.lua
│── airui_table.lua
│── airui_tabview.lua
│── airui_win.lua
│── lcd_drv.lua
│── tp_drv.lua
│── readme.md
5.1 文件说明
1、main.lua:整个项目的入口点。它负责初始化系统环境
2、images:
xxx.jpg:演示图片文件(和lua脚本文件一起烧录,会自动放置在/luadb/目录下)
3、airui_all_component.lua:所有组件综合演示
4、airui_bar.lua:(动态)进度条组件演示
5、airui_button.lua:按钮组件演示
6、airui_chart.lua:图表组件演示
7、airui_container.lua:容器组件演示
8、airui_dropdown.lua:下拉框组件演示
9、airui_hzfont.lua:HzFont 矢量字体特性演示
10、airui_image.lua:图片组件演示
11、airui_input.lua:输入框和虚拟键盘演示
12、airui_label.lua:标签组件演示
13、airui_msgbox.lua:消息框组件演示
14、airui_qrcode.lua:二维码组件演示
15、airui_switch.lua:开关组件演示
16、airui_switch_page.lua:多页面切换功能演示
17、airui_table.lua:表格组件演示
18、airui_tabview.lua:选项卡组件演示
19、airui_win.lua:窗口组件演示
20、lcd_drv.lua:LCD 显示驱动
21、tp_drv.lua:触摸面板驱动
六、代码详解
6.1 main.lua
主程序文件 main.lua 是整个项目的入口点。它负责初始化系统环境。
-- 加载显示驱动
require("lcd_drv")
-- 加载触摸驱动
require("tp_drv")
-- 引入演示模块(每次只选择一个运行)
-- require("airui_label") --动态更新标签演示
-- require("airui_button") --按钮演示
-- require("airui_image") --图片显示演示
-- require("airui_container") --容器演示
-- require("airui_bar") --动态进度条演示
-- require("airui_dropdown") --下拉框演示
-- require("airui_switch") --开关组件演示
-- require("airui_msgbox") --消息框组件演示
-- require("airui_input") --输入框和键盘演示
-- require("airui_tabview") --选项卡演示
-- require("airui_table") --表格演示
-- require("airui_win") --标签窗口演示
require("airui_all_component") --所有组件综合演示
-- require("airui_switch_page") --页面切换演示
-- require("airui_hzfont") --内置软件矢量字体演示
-- require("airui_chart") --图表组件演示
-- require("airui_qrcode") --二维码组件演示
-- 用户代码已结束
-- 结尾总是这一句
sys.run()
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
6.2 airui_all_component.lua
本文件演示所有AirUI组件的综合用法,展示完整UI界面。
local function ui_main()
-- 初始化硬件
-- 创建主容器
local main_container = airui.container({
x = 0,
y = 0,
w = 800,
h = 480,
color = 0xF5F5F5,
})
-- 1. 标题区域
local title_bar = airui.container({
parent = main_container,
x = 0,
y = 0,
w = 800,
h = 60,
color = 0x007AFF,
})
local title_label = airui.label({
parent = title_bar,
text = "AirUI 全部组件演示",
x = 20,
y = 20,
w = 760,
h = 30,
})
-- 2. 左列组件
local left_col = airui.container({
parent = main_container,
x = 20,
y = 70,
w = 380,
h = 380,
color = 0xFFFFFF,
radius = 8,
})
-- 2.1 文本输入框组件
airui.label({
parent = left_col,
text = "文本输入",
x = 20,
y = 20,
w = 100,
h = 25,
})
-- 创建虚拟键盘
local keyboard = airui.keyboard({
x = 0,
y = -20, -- 底部留20像素边距
w = 800,
h = 250,
mode = "text",
auto_hide = true,
})
-- 创建输入框并绑定键盘
local text_input = airui.textarea({
parent = left_col,
x = 20,
y = 50,
w = 340,
h = 60,
max_len = 50,
text = "示例文本",
placeholder = "请输入...",
keyboard = keyboard,
on_text_change = function(text)
log.info("textarea", text)
end
})
-- 2.2 进度条组件
airui.label({
parent = left_col,
text = "进度条",
x = 20,
y = 130,
w = 100,
h = 25,
})
local progress_bar = airui.bar({
parent = left_col,
x = 20,
y = 160,
w = 340,
h = 20,
value = 65,
bg_color = 0xE0E0E0,
indicator_color = 0x4CAF50,
radius = 10,
})
-- 2.3 按钮组件
local test_btn = airui.button({
parent = left_col,
x = 20,
y = 200,
w = 150,
h = 40,
text = "更新进度条",
on_click = function()
local current = progress_bar:get_value()
local new_value = current + 10
if new_value > 100 then
new_value = 0
end
progress_bar:set_value(new_value, true)
log.info("progress", "进度更新为: " .. new_value .. "%")
end
})
-- 2.4 消息框按钮
local msgbox_btn = airui.button({
parent = left_col,
x = 200,
y = 200,
w = 150,
h = 40,
text = "显示消息框",
on_click = function()
local msgbox = airui.msgbox({
title = "提示",
text = "这是消息框演示\n点击确定关闭",
buttons = { "确定", "取消" },
timeout = 2000,
on_action = function(self, label)
log.info("msgbox", "点击了: " .. label)
self:hide()
end
})
end
})
-- 2.5 下拉框组件
airui.label({
parent = left_col,
text = "下拉选择",
x = 20,
y = 250,
w = 100,
h = 25,
})
local dropdown = airui.dropdown({
parent = left_col,
x = 20,
y = 280,
w = 200,
h = 40,
options = { "选项一", "选项二", "选项三", "选项四" },
default_index = 0,
on_change = function(self, index)
local texts = { "选项一", "选项二", "选项三", "选项四" }
log.info("dropdown", "选择了: " .. texts[index + 1])
end
})
-- 2.6 开关组件
airui.label({
parent = left_col,
text = "开关",
x = 240,
y = 250,
w = 60,
h = 30,
})
-- 使用一个变量来跟踪当前状态
local is_on = true -- 初始为ON,与switch的checked=true对应
local toggle_switch = airui.switch({
parent = left_col,
x = 240,
y = 280,
checked = true,
on_change = function(self)
-- 切换状态
is_on = not is_on
-- 根据状态更新日志
if is_on then
log.info("当前状态: 开")
else
log.info("当前状态: 关")
end
end
})
-- 2.7 在左列底部添加图表组件(折线图)
airui.label({
parent = left_col,
text = "图表(简化)",
x = 20,
y = 320,
w = 100,
h = 20,
})
local chart = airui.chart({
parent = left_col,
x = 20,
y = 340,
w = 340,
h = 40,
type = "line",
y_min = 0,
y_max = 100,
point_count = 30,
line_color = 0x00b4ff,
line_width = 1,
point_radius = 1,
legend = false,
x_axis = { enable = false },
y_axis = { enable = false },
})
-- 设置一些示例数据
chart:set_values(1, {30, 45, 60, 55, 70, 65, 80, 75, 90, 85, 95})
-- 3. 右列组件
local right_col = airui.container({
parent = main_container,
x = 420,
y = 70,
w = 360,
h = 380,
color = 0xFFFFFF,
radius = 8,
})
-- 右列标题
airui.label({
parent = right_col,
text = "数据表格",
x = 20,
y = 20,
w = 320,
h = 25,
})
-- 3.1 表格组件
local data_table = airui.table({
parent = right_col,
x = 20,
y = 60,
w = 320,
h = 220,
rows = 3,
cols = 3,
col_width = { 100, 100, 100 },
border_color = 0xCCCCCC
})
-- 设置表格内容
data_table:set_cell_text(0, 0, "姓名")
data_table:set_cell_text(0, 1, "年龄")
data_table:set_cell_text(0, 2, "城市")
data_table:set_cell_text(1, 0, "张三")
data_table:set_cell_text(1, 1, "25")
data_table:set_cell_text(1, 2, "北京")
data_table:set_cell_text(2, 0, "李四")
data_table:set_cell_text(2, 1, "30")
data_table:set_cell_text(2, 2, "上海")
-- 3.2 二维码组件
airui.label({
parent = right_col,
text = "二维码",
x = 20,
y = 290,
w = 100,
h = 20,
})
local qrcode = airui.qrcode({
parent = right_col,
x = 125, -- 居中 (360-70)/2 = 145, 但考虑标签文字占用左边距,微调
y = 310,
size = 70,
data = "https://docs.openluat.com/",
dark_color = 0x000000,
light_color = 0xFFFFFF,
quiet_zone = true
})
-- 4. 底部状态栏
local status_bar = airui.container({
parent = main_container,
x = 0,
y = 460,
w = 800,
h = 20,
color = 0xCFCFCF,
})
airui.label({
parent = status_bar,
text = "AirUI Demo v1.1",
x = 20,
y = 2,
w = 760,
h = 16,
})
end
sys.taskInit(ui_main)
6.3 airui_bar.lua
本文件演示airui.bar组件的用法,展示动态变化的进度条。
local direction = 1 -- 变化方向
local current = 0 -- 当前值
local function ui_main()
-- 初始化硬件
-- 创建进度条
local progress = airui.bar({
x = 100,
y = 200,
w = 280,
value = 30
})
-- 主循环
while true do
-- 更新进度条值
current = current + direction
if current >= 100 then
direction = -1
elseif current <= 0 then
direction = 1
end
progress:set_value(current, true)
sys.wait(50)
end
end
sys.taskInit(ui_main)
6.4 airui_button.lua
本文件演示airui.button组件的用法,展示可点击按钮。
local function ui_main()
-- 初始化硬件
-- 创建按钮
-- 示例1:创建一个基础按钮
local btn1 = airui.button({
text = "点我",
x = 20,
y = 80,
on_click = function()
log.info("btn", "tap")
end
})
-- 示例2:创建一个支持切换显示内容的按钮,V1.0.3更新
local is_play = false
local btn2 = airui.button({
text = "播放",
x = 20,
y = 180,
on_click = function(self)
if is_play then
-- 当前是“停止”,点击后切换为“播放”
self:set_text("播放")
is_play = false
else
-- 当前是“播放”,点击后切换为“停止”
self:set_text("停止")
is_play = true
end
end
})
end
sys.taskInit(ui_main)
6.5 airui_chart.lua
本文件演示airui.chart组件的用法,展示折线图动态数据更新。
local function ui_main()
-- 初始化硬件
-- 创建图表(折线图)
local chart = airui.chart({
x = 20,
y = 20,
w = 760,
h = 440,
type = "line", -- 折线图
y_min = 0,
y_max = 100,
point_count = 120, -- 数据点总数
update_mode = "shift", -- 滚动更新
line_color = 0x00b4ff, -- 主系列颜色
line_width = 2,
point_radius = 2, -- 显示数据点
hdiv = 6,
vdiv = 6,
legend = true, -- 显示图例
x_axis = { enable = true, min = 0, max = 120, ticks = 6, unit = "s" },
y_axis = { enable = true, min = 0, max = 100, ticks = 6, unit = "%" }
})
-- 添加第二个系列
local sid2 = chart:add_series({ color = 0xff6b35, name = "avg" })
-- 添加第三个系列
local sid3 = chart:add_series({ color = 0x22c55e, name = "diff" })
-- 设置第一个系列名称
chart:set_series_name(1, "raw")
-- 设置初始数据
chart:set_values(1, {50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70})
chart:set_values(sid2, {50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60})
chart:set_values(sid3, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
-- 模拟动态推送(可选)
sys.timerLoopStart(function()
-- 随机生成新数据并推入
local v1 = 50 + math.random(-20, 20)
local v2 = 50 + math.random(-15, 15)
local v3 = v1 - v2
chart:push(1, v1)
chart:push(sid2, v2)
chart:push(sid3, v3)
end, 1000)
end
sys.taskInit(ui_main)
6.6 airui_container.lua
本文件演示airui.container组件的用法,展示如何创建容器并添加子组件。
local function ui_main()
-- 初始化硬件
-- 创建红色容器
local box = airui.container({
x = 100,
y = 100,
w = 100,
h = 100,
color = 0xff0000
})
-- 在容器中添加标签
local label = airui.label({
parent = box, -- 指定父容器
text = "容器中的标签",
x = 10,
y = 50,
w = 100,
h = 100,
})
end
sys.taskInit(ui_main)
6.7 airui_dropdown.lua
本文件演示airui.dropdown组件的用法,展示下拉选择功能。
local function ui_main()
-- 初始化硬件
-- 创建标签显示选择结果
local label = airui.label({
text = "请选择选项",
x = 50,
y = 80,
w = 200,
h = 40,
})
-- 创建下拉框
local dd = airui.dropdown({
x = 50,
y = 120,
w = 120,
h = 40,
options = { "选项A", "选项B", "选项C" },
default_index = 1,
on_change = function(self, index)
-- 更新标签显示选择结果
local texts = { "选项A", "选项B", "选项C" }
label:set_text("选择了: " .. texts[index + 1])
end
})
end
sys.taskInit(ui_main)
6.8 airui_hzfont.lua
本文件演示HzFont矢量字体的各项特性,包括全字号无级缩放、抗锯齿优化和字体使用自由。
local function ui_main()
-- 初始化硬件
-- 创建主容器(白色背景)
local main_container = airui.container({
x = 0,
y = 0,
w = 800,
h = 480,
color = 0xFFFFFF,
})
-- 标题栏(蓝色)
local title_bar = airui.container({
parent = main_container,
x = 0,
y = 0,
w = 800,
h = 80,
color = 0x2196F3,
})
-- 标题:使用大字号 + 白色
local title_label = airui.label({
parent = title_bar,
text = "HzFont 矢量字体演示 (Vector Font Demo)",
x = 10,
y = 20,
w = 780,
h = 40,
font_size = 32, -- 大字号突出标题
color = 0xFFFFFF, -- 白色文字
align = airui.TEXT_ALIGN_CENTER
})
-- 内容区域(浅灰色圆角背景)
local content_area = airui.container({
parent = main_container,
x = 40,
y = 100,
w = 720,
h = 340,
color = 0xF8F9FA,
radius = 8,
})
-- 第1行:超大字号演示无级缩放(含英文、符号)
local line1_label = airui.label({
parent = content_area,
text = "全字号无级缩放:字号 48 (Scale: 48px)",
x = 20,
y = 20,
w = 680,
h = 120,
font_size = 48, -- 超大字号
color = 0xE63946, -- 鲜艳红色
})
-- 第2行:中等字号 + 智能抗锯齿(多颜色)
local line2_label = airui.label({
parent = content_area,
text = "智能抗锯齿优化:字号 28 Anti-aliasing 中文 English",
x = 20,
y = 150,
w = 680,
h = 70,
font_size = 28, -- 中等字号
color = 0x2A9D8F, -- 翠绿色
})
-- 第3行:小字号展示多语言和符号(长文本)
local line3_label = airui.label({
parent = content_area,
text = "字体使用高度自由:内置字库 / 外部.ttf。支持中英符号",
x = 20,
y = 240,
w = 680,
h = 30,
font_size = 24, -- 较小字号,适合多行文本
color = 0x264653, -- 深蓝灰色
})
end
sys.taskInit(ui_main)
6.9 airui_image.lua
本文件演示airui.image组件的用法,展示图片显示功能。
local function ui_main()
-- 初始化硬件
-- 创建可点击图片
local img = airui.image({
src = "/luadb/dingwei_50x50.png",
x = 336,
y = 176,
w = 128,
h = 128,
opacity = 100,
on_click = function(self)
log.info("image", "图片被点击了")
end
})
-- 创建半透明图片
local img1 = airui.image({
src = "/luadb/logo.jpg",
x = 20,
y = 20,
w = 80,
h = 80,
-- opacity = 100, -- jpg不支持调整透明度
})
end
sys.taskInit(ui_main)
6.10 airui_input.lua
本文件演示airui.textarea和airui.keyboard组件的用法,展示文本输入功能。
local function ui_main()
-- 初始化硬件
-- 创建虚拟键盘
local keyboard = airui.keyboard({
x = 0,
y = -20, -- 底部留20像素边距
w = 800,
h = 250,
mode = "text",
auto_hide = true,
})
-- 创建文本输入框
local textarea = airui.textarea({
x = 0,
y = 0,
w = 800,
h = 150,
max_len = 512,
text = "在这里输入文字",
placeholder = "点击输入...",
keyboard = keyboard
})
-- 创建按钮
local btn = airui.button({
x = 20,
y = 180,
text = "提交",
on_click = function()
airui.msgbox({
title = "提交内容为",
text = textarea:get_text(),
buttons = { "确定" },
on_action = function(self, label)
if label == "确定" then
self:hide()
end
end
})
end
})
end
sys.taskInit(ui_main)
6.11 airui_label.lua
本文件演示airui.label组件的用法,展示文本标签功能。
local function ui_main()
-- 初始化硬件
-- 创建文本标签
local label1 = airui.label({
text = "Hello, World!",
x = 20,
y = 80,
w = 100,
h = 40,
})
-- 创建图标标签
local label2 = airui.label({
symbol = airui.SYMBOL_SETTINGS,
x = 120,
y = 80,
w = 20,
h = 20,
on_click = function(self)
log.info("label2", "设置图标被点击")
end
})
end
sys.taskInit(ui_main)
6.12 airui_msgbox.lua
本文件演示airui.msgbox组件的用法,展示消息提示框功能。
local function ui_main()
-- 初始化硬件
-- 创建消息框
local box = airui.msgbox({
title = "通知",
text = "2026年你会发财!",
buttons = { "确定" },
on_action = function(self, label)
if label == "确定" then
self:hide()
end
end
})
end
sys.taskInit(ui_main)
6.13 airui_qrcode.lua
本文件演示airui.qrcode组件的用法,展示二维码生成与切换。
local function ui_main()
-- 初始化硬件
-- 创建二维码
local qrcode = airui.qrcode({
x = 40,
y = 40,
size = 220, -- 正方形尺寸
data = "https://docs.openluat.com/", -- 二维码内容
dark_color = 0x000000, -- 深色模块颜色
light_color = 0xFFFFFF, -- 浅色模块颜色
quiet_zone = true -- 四周留白
})
if not qrcode then
log.error("qrcode", "创建二维码失败")
return
end
-- 添加一个标签说明
airui.label({
x = 40,
y = 280,
w = 720,
h = 40,
text = "扫描上方二维码访问 LuatOS 官网",
font_size = 20,
color = 0x333333
})
end
sys.taskInit(ui_main)
6.14 airui_switch.lua
本文件演示airui.switch组件的用法,展示开关切换功能。
local function ui_main()
-- 初始化硬件
-- 创建标签显示状态
local label = airui.label({
text = "当前状态: 开",
x = 20,
y = 80,
w = 150,
h = 40,
})
-- 创建开关
-- 使用一个变量来跟踪当前状态
local is_on = true
local sw = airui.switch({
x = 20,
y = 120,
on_change = function()
-- 切换状态
is_on = not is_on
-- 根据状态更新文本
if is_on then
label:set_text("当前状态: 开")
else
label:set_text("当前状态: 关")
end
end
})
end
sys.taskInit(ui_main)
6.15 airui_switch_page.lua
本文件演示如何使用容器组件实现多页面切换功能。
local current_page = 1
local total_pages = 3
local pages = {}
local function ui_main()
-- 初始化硬件
-- 创建主容器
local main_container = airui.container({
x = 0,
y = 0,
w = 800,
h = 480,
color = 0xF8F9FA,
})
-- 创建标题栏
local title_bar = airui.container({
parent = main_container,
x = 0,
y = 0,
w = 800,
h = 80,
color = 0x007AFF,
})
local title_label = airui.label({
parent = title_bar,
text = "页面切换演示",
x = 20,
y = 20,
w = 760,
h = 40,
})
local page_indicator = airui.label({
parent = title_bar,
text = "第1页 / 共3页",
x = 600,
y = 20,
w = 180,
h = 40,
})
-- 创建内容区域
local content_area = airui.container({
parent = main_container,
x = 20,
y = 100,
w = 760,
h = 320,
color = 0xFFFFFF,
radius = 10,
})
-- 创建三个页面
for i = 1, total_pages do
pages[i] = airui.container({
parent = content_area,
x = 0,
y = 0,
w = 760,
h = 320,
color = 0xFFFFFF,
})
-- 设置页面初始状态(只显示第一个页面)
if i ~= 1 then
pages[i]:set_hidden(true)
end
-- 为每个页面添加不同的内容
if i == 1 then
-- 第一页:欢迎页面
local welcome_label = airui.label({
parent = pages[i],
text = "欢迎使用页面切换演示",
x = 0,
y = 50,
w = 760,
h = 50,
})
local desc_label = airui.label({
parent = pages[i],
text = "这是一个演示多页面切换功能的示例\n使用容器组件实现页面切换\n点击下方按钮切换页面",
x = 0,
y = 120,
w = 760,
h = 100,
})
elseif i == 2 then
-- 第二页:设置页面
airui.label({
parent = pages[i],
text = "设置页面",
x = 0,
y = 30,
w = 760,
h = 40,
})
-- 设置项目1
airui.label({
parent = pages[i],
text = "开关设置",
x = 50,
y = 90,
w = 200,
h = 30,
})
local switch1 = airui.switch({
parent = pages[i],
x = 250,
y = 95,
checked = true,
on_change = function()
log.info("page2", "开关1状态改变")
end
})
-- 设置项目2
airui.label({
parent = pages[i],
text = "亮度调节",
x = 50,
y = 140,
w = 200,
h = 30,
})
local brightness_bar = airui.bar({
parent = pages[i],
x = 250,
y = 145,
w = 200,
h = 20,
value = 75,
indicator_color = 0xFF9800,
})
-- 设置项目3
airui.label({
parent = pages[i],
text = "模式选择",
x = 50,
y = 190,
w = 200,
h = 30,
})
local mode_dropdown = airui.dropdown({
parent = pages[i],
x = 250,
y = 190,
w = 200,
h = 40,
options = { "自动模式", "手动模式", "节能模式" },
default_index = 0,
})
elseif i == 3 then
-- 第三页:数据页面
airui.label({
parent = pages[i],
text = "数据展示",
x = 0,
y = 30,
w = 760,
h = 40,
})
-- 创建数据表格
local data_table = airui.table({
parent = pages[i],
x = 50,
y = 70,
w = 660,
h = 240,
rows = 5,
cols = 4,
col_width = { 200, 150, 150, 150 },
border_color = 0xCCCCCC
})
-- 设置表头
data_table:set_cell_text(0, 0, "设备名称")
data_table:set_cell_text(0, 1, "温度")
data_table:set_cell_text(0, 2, "湿度")
data_table:set_cell_text(0, 3, "状态")
-- 设置数据
data_table:set_cell_text(1, 0, "传感器1")
data_table:set_cell_text(1, 1, "25°C")
data_table:set_cell_text(1, 2, "65%")
data_table:set_cell_text(1, 3, "正常")
data_table:set_cell_text(2, 0, "传感器2")
data_table:set_cell_text(2, 1, "28°C")
data_table:set_cell_text(2, 2, "70%")
data_table:set_cell_text(2, 3, "正常")
data_table:set_cell_text(3, 0, "传感器3")
data_table:set_cell_text(3, 1, "22°C")
data_table:set_cell_text(3, 2, "60%")
data_table:set_cell_text(3, 3, "正常")
data_table:set_cell_text(4, 0, "传感器4")
data_table:set_cell_text(4, 1, "30°C")
data_table:set_cell_text(4, 2, "75%")
data_table:set_cell_text(4, 3, "警告")
end
end
-- 创建底部导航栏
local nav_bar = airui.container({
parent = main_container,
x = 0,
y = 430,
w = 800,
h = 50,
color = 0xFFFFFF,
})
-- 创建导航按钮容器
local btn_container = airui.container({
parent = nav_bar,
x = 100,
y = 5,
w = 600,
h = 40,
color = 0xFFFFFF,
})
-- 创建上一页按钮
local prev_btn = airui.button({
parent = btn_container,
x = 0,
y = 0,
w = 120,
h = 40,
text = "上一页",
on_click = function()
if current_page > 1 then
-- 隐藏当前页面
pages[current_page]:set_hidden(true)
current_page = current_page - 1
-- 显示新页面
pages[current_page]:set_hidden(false)
page_indicator:set_text("第" .. current_page .. "页 / 共3页")
log.info("page_switch", "切换到第 " .. current_page .. " 页")
end
end
})
-- 创建页面按钮
local page_btn_x = 140
for i = 1, total_pages do
local btn_text = "第" .. i .. "页"
local page_btn = airui.button({
parent = btn_container,
x = page_btn_x,
y = 0,
w = 80,
h = 40,
text = btn_text,
on_click = function()
-- 隐藏所有页面
for j = 1, total_pages do
pages[j]:set_hidden(true)
end
-- 显示选中的页面
current_page = i
pages[current_page]:set_hidden(false)
page_indicator:set_text("第" .. current_page .. "页 / 共3页")
log.info("page_switch", "跳转到第 " .. current_page .. " 页")
end
})
page_btn_x = page_btn_x + 90
end
-- 创建下一页按钮
local next_btn = airui.button({
parent = btn_container,
x = 480,
y = 0,
w = 120,
h = 40,
text = "下一页",
on_click = function()
if current_page < total_pages then
-- 隐藏当前页面
pages[current_page]:set_hidden(true)
current_page = current_page + 1
-- 显示新页面
pages[current_page]:set_hidden(false)
page_indicator:set_text("第" .. current_page .. "页 / 共3页")
log.info("page_switch", "切换到第 " .. current_page .. " 页")
end
end
})
end
sys.taskInit(ui_main)
6.16 airui_table.lua
本文件演示airui.table组件的用法,展示表格功能。
local function ui_main()
-- 初始化硬件
-- 创建3行3列的表格
local tbl = airui.table({
x = 10,
y = 10,
h = 200,
w = 410,
rows = 3,
cols = 3
})
-- 设置表格标题
tbl:set_cell_text(0, 0, "姓名")
tbl:set_cell_text(0, 1, "年龄")
tbl:set_cell_text(0, 2, "城市")
-- 设置表格内容
tbl:set_cell_text(1, 0, "张三")
tbl:set_cell_text(1, 1, "25")
tbl:set_cell_text(1, 2, "北京")
tbl:set_cell_text(2, 0, "李四")
tbl:set_cell_text(2, 1, "30")
tbl:set_cell_text(2, 2, "上海")
end
sys.taskInit(ui_main)
6.17 airui_tabview.lua
本文件演示airui.tabview组件的用法,展示多页面切换功能。
local function ui_main()
-- 初始化硬件
-- 创建选项卡视图
local tv = airui.tabview({
x = 0,
y = 0,
w = 800,
h = 480,
tabs = { "页面A", "页面B", "页面C", "页面D", "页面E" }
})
-- 获取各个页面容器
local page1 = tv:get_content(0)
local page2 = tv:get_content(1)
local page3 = tv:get_content(2)
local page4 = tv:get_content(3)
local page5 = tv:get_content(4)
-- 在每个页面中添加标签
airui.label({ parent = page1, text = "这是页面A", x = 200, y = 80 })
airui.label({ parent = page2, text = "这是页面B", x = 200, y = 80 })
airui.label({ parent = page3, text = "这是页面C", x = 200, y = 80 })
airui.label({ parent = page4, text = "这是页面D", x = 200, y = 80 })
airui.label({ parent = page5, text = "这是页面E", x = 200, y = 80 })
end
sys.taskInit(ui_main)
6.18 airui_win.lua
本文件演示airui.win组件的用法,展示窗口功能。
local function ui_main()
-- 初始化硬件
-- 创建窗口
local win1 = airui.win({
title = "示例窗口",
x = 10,
y = 10,
w = 600,
h = 400,
close_btn = true,
auto_center = false,
style = "radius",
-- V1.0.4版本实现点击关闭按钮关闭win组件
on_close = function(self)
log.info("win", "窗口已关闭")
end
})
-- 在窗口中添加标签
local label1 = airui.label({
parent = win1,
text = "窗口中的内容",
x = 20,
y = 20,
})
end
sys.taskInit(ui_main)
6.19 lcd_drv.lua
LCD显示驱动模块,基于lcd核心库。
local function lcd_drv_init()
local result = lcd.init("h050iwv",
{
pin_pwr = 8, -- 背光控制引脚GPIO端口号
port = lcd.RGB, -- 驱动端口
direction = 0, -- lcd屏幕方向 0:0° 1:90° 2:180° 3:270°,屏幕方向和分辨率保存一致
w = 800, -- lcd 水平分辨率
h = 480, -- lcd 竖直分辨率
xoffset = 0, -- x偏移(不同屏幕ic 不同屏幕方向会有差异)
yoffset = 0, -- y偏移(不同屏幕ic 不同屏幕方向会有差异)
})
log.info("lcd.init", result)
if result then
-- 开启缓冲区, 刷屏速度会加快, 但也消耗2倍屏幕分辨率的内存
lcd.setupBuff(nil, true)
lcd.autoFlush(false)
-- 初始化AirUI
local width, height = lcd.getSize()
local result = airui.init(width, height)
if not result then
log.error("airui", "init failed")
return result
end
-- 加载中文字体
if rtos.bsp() ~= "Air8101" then
-- PC端/Air8000/780EHM 从14号固件/114号固件中加载hzfont字库,从而支持12-255~号中文显示
airui.font_load({
type = "hzfont", -- 字体类型,可选 "hzfont" 或 "bin"
path = nil, -- 字体路径,对于 "hzfont",传 nil 则使用内置字库
size = 20, -- 字体大小,默认 16
cache_size = 1048, -- 缓存字数大小,默认 2048
antialias = 1, -- 抗锯齿等级1-3,默认 1
})
else
-- Air8101使用104号固件将字体文件烧录到文件系统,从文件系统中加载hzfont字库,从而支持12-255号中文显示
airui.font_load({
type = "hzfont", -- 字体类型,可选 "hzfont" 或 "bin"
path = "/MiSans_gb2312.ttf", -- 字体路径,对于 "hzfont",传 nil 则使用内置字库
size = 20, -- 字体大小,默认 16
cache_size = 1048, -- 缓存字数大小,默认 2048
antialias = 1, -- 抗锯齿等级1-3,默认 1
-- load_to_psram= true,
global = true
})
end
-- 开启背光引脚供电
gpio.setup(8, 1)
-- 查询当前固件内AirUI核心库版本,V1.0.3新增接口
log.info("airui", "version -> " .. airui.version())
return result
end
end
lcd_drv_init()
6.20 tp_drv.lua
触摸面板驱动模块,基于tp核心库。
local function tp_drv_init()
-- 初始化软件I2C,接口i2c.createSoft(scl, sda, delay)
-- 参数说明:
-- 0: SCL引脚编号
-- 1: SDA引脚编号
local result = i2c.createSoft(0, 1)
if type(result) ~= "userdata" then
log.error("tp_drv.init i2c.createSoft error")
return false
end
-- 此处触摸IC数据读取使用的是软件I2C接口
-- 参数说明:
-- "gt911": 触摸控制器型号
-- port: I2C接口对象
-- pin_rst: 复位引脚编号
-- pin_int: 中断引脚编号
-- w: 触摸面板宽度
-- h: 触摸面板高度
result = tp.init("gt911", { port = result, pin_rst = 28, pin_int = 7, w = 800, h = 480 })
log.info("tp.init", result)
if rtos.bsp() ~= "PC" then
-- 绑定触摸设备到AirUI输入设备
airui.device_bind_touch(result)
-- 在PC模拟器上启用系统键盘输入
airui.keyboard_enable_system(true)
else
if not result then
log.error("ui_main", "触摸初始化失败")
return result
else
-- 绑定触摸设备到AirUI输入设备
return airui.device_bind_touch(result)
end
end
end
tp_drv_init()
七、显示效果展示
7.1 硬件准备
- 按照硬件接线表连接所有设备
- 通过 TYPE-C USB 口供电
- 检查所有接线无误
7.2 软件配置
在 main.lua 中选择要运行的演示模块:
-- 加载显示驱动
require("lcd_drv")
-- 加载触摸驱动
require("tp_drv")
-- 引入演示模块(每次只选择一个运行)
-- require("airui_label") --动态更新标签演示
-- require("airui_button") --按钮演示
-- require("airui_image") --图片显示演示
-- require("airui_container") --容器演示
-- require("airui_bar") --动态进度条演示
-- require("airui_dropdown") --下拉框演示
-- require("airui_switch") --开关组件演示
-- require("airui_msgbox") --消息框组件演示
-- require("airui_input") --输入框和键盘演示
-- require("airui_tabview") --选项卡演示
-- require("airui_table") --表格演示
-- require("airui_win") --标签窗口演示
require("airui_all_component") --所有组件综合演示
-- require("airui_switch_page") --页面切换演示
-- require("airui_hzfont") --内置软件矢量字体演示
-- require("airui_chart") --图表组件演示
-- require("airui_qrcode") --二维码组件演示
7.3 软件烧录
- 使用 Luatools 烧录对应型号的最新内核固件
- 下载本项目所有脚本文件和图片文件
- 将演示图片文件(如
logo.jpg等)同.lua脚本文件一起烧录到脚本分区 - 设备自动重启后开始运行选定的演示模块
7.4 功能测试
| 组件 | 输入法 |
![]() | ![]() |
八、使用合宙 LuatOS-PC 模拟器仿真 airui
8.1 PC 模拟器说明
- 合宙 LuatOS-PC 模拟器是一个能在 win10/win11 上模拟运行 lua 脚本的仿真软件,内置 LuatOS 内核固件,运行.lua 脚本效果与实际设备类似;
- 目前 PC 模拟器可以通过 LuaTools 工具的资源管理器进行下载,所以我们需要先下载安装 LuaTools 工具,然后再通过 LuaTools 工具来下载 LuatOS-PC 模拟器,最后通过 LuatOS-PC 模拟器运行 airui演示 demo;
8.2 LuatOS-PC 模拟器安装步骤
1、点击下载:Luatools v3 下载调试工具
2、通过 LuaTools 工具下载 LuatOS-PC 模拟器
- LuaTools 工具安装完毕后,点击首页面左上角的--账户--打开资源下载
- 选择-公共资源--LuatOS 的 PC 模拟器--选择最新版本 LuatOS-PC 模拟器--点击开始下载(非刷机)


4.3 下载底层固件和上层运行脚本
- 下载运行所需固件,点击资源管理--选择 Air8101 的 LuatOS 固件--下载V2024版本及以上的 14/114 号固件
- 下载本演示 demo 内所有.lua 脚本文件、images 文件夹内的图片(以下图片仅是示范,请根据实际情况下载对应固件)

4.4 使用 LuatOS-PC 模拟器仿真 运行 airui 演示 demo
- 返回 Luatloos 工具首页,点击--项目管理测试

- 创建一个项目并命名

- 选择固件刚才下载的固件--点击打开,路径在 Luatools 目录下 resource\LuatOS_Air8101\LuatOS-SoC_VXXXX_Air8101(以下图片仅是示范,请根据实际情况选择对应固件)

- 将下载的 demo 图片资源和.lua文件拖入到项目管理内的脚本和资源列表区域--勾选添加默认 lib--点击模拟器运行--出来的界面就是 demo 在实际设备上运行界面的仿真,可以用鼠标进行交互(以下图片仅是示范,请根据实际情况选择对应固件和脚本)

- 如需切换 demo 内的演示内容,可打开下载脚本文件中的 mian.lua 文件,将需要演示 demo 的 require 前面的注释符"--"去掉,将不需要演示 demo 的 require 前面加上注释符“--”。修改后保存代码文件,再点击模拟器运行,就会出现所 require 的 demo 对应的界面仿真。
- 比如:需要演示下拉框组件,将 main.lua 文件中的-- require("airui_dropdown") 改为 require("airui_dropdown") ,并把其他加载的组件改为注释状态。

九、故障排除
9.1 常见问题及解决方案
1、显示异常
- 检查 LCD 接线是否存在异常
- 确认 lcd_drv.lua 内屏幕型号及其参数配置是否正确
2、触摸无响应
- 检查 I2C 接线是否存在异常
- 确认确认 tp_drv.lua 内触摸芯片型号配置正确
3、字体显示异常
- 确认选择的字体驱动与硬件匹配
- 检查固件版本是否支持所选字体
4、图片无法显示
- 确认图片文件已正确烧录
- 检查文件路径和名称是否正确
5、系统运行缓慢
- 检查是否有过多的组件同时渲染
- 适当调整刷新间隔时间
9.2 调试技巧
- 使用
log.info()输出调试信息 - 检查系统内存使用情况
- 逐步启用组件排查问题

