App Inventor 2 UI进阶教程


一、手机分辨率适配

1.1 获取屏幕信息

初始化全局变量 屏幕宽度 = 0
初始化全局变量 屏幕高度 = 0
初始化全局变量 屏幕密度 = 0
初始化全局变量 基准宽度 = 360  // 设计基准宽度(dp)

当 Screen1.初始化 时
  设置 全局变量 屏幕宽度 = Screen1.宽度
  设置 全局变量 屏幕高度 = Screen1.高度
  设置 全局变量 缩放比例 = 全局变量 屏幕宽度 / 全局变量 基准宽度
  
  调用 适配界面()

1.2 动态适配组件

过程 适配组件(组件, 基准宽度, 基准高度, 基准字体)
  // 按比例缩放
  调用 组件.设置属性("宽度", 向下取整(基准宽度 * 全局变量 缩放比例))
  调用 组件.设置属性("高度", 向下取整(基准高度 * 全局变量 缩放比例))
  调用 组件.设置属性("字体大小", 向下取整(基准字体 * 全局变量 缩放比例))
过程结束

过程 适配界面
  // 适配标题
  调用 适配组件(Label_Title, 320, 50, 20)
  
  // 适配按钮
  调用 适配组件(Button_Main, 200, 60, 16)
  
  // 适配图片
  调用 适配组件(Image_Logo, 100, 100, 0)
过程结束

1.3 屏幕方向适配

当 Screen1.屏幕方向改变(是否横屏) 时
  设置 全局变量 屏幕宽度 = Screen1.宽度
  设置 全局变量 屏幕高度 = Screen1.高度
  
  如果 是否横屏 = 真 则
    // 横屏布局
    设置 HorizontalArrangement1.可见 = 真
    设置 VerticalArrangement1.可见 = 假
  否则
    // 竖屏布局
    设置 HorizontalArrangement1.可见 = 假
    设置 VerticalArrangement1.可见 = 真
  如果结束
  
  调用 适配界面()

二、虚拟摇杆

初始化全局变量 摇杆中心X = 0
初始化全局变量 摇杆中心Y = 0
初始化全局变量 摇杆半径 = 60
初始化全局变量 摇杆激活 = 假
初始化全局变量 摇杆方向X = 0
初始化全局变量 摇杆方向Y = 0

当 Screen1.初始化 时
  // 摇杆放在左下角
  设置 全局变量 摇杆中心X = 100
  设置 全局变量 摇杆中心Y = Screen1.高度 - 100
  
  // 初始化摇杆位置
  设置 ImageSprite_JoyBase.X = 全局变量 摇杆中心X - 60
  设置 ImageSprite_JoyBase.Y = 全局变量 摇杆中心Y - 60
  设置 ImageSprite_JoyKnob.X = 全局变量 摇杆中心X - 25
  设置 ImageSprite_JoyKnob.Y = 全局变量 摇杆中心Y - 25
  
  调用 时钟1.开启定时器(间隔: 50)

当 Canvas1.触摸开始(X, Y) 时
  // 检测是否在摇杆区域
  设置 全局变量 距离 = 平方根((X - 全局变量 摇杆中心X) ^ 2 + (Y - 全局变量 摇杆中心Y) ^ 2)
  如果 全局变量 距离 < 全局变量 摇杆半径 * 1.5 则
    设置 全局变量 摇杆激活 = 真
  如果结束

当 Canvas1.被拖动(起始X, 起始Y, 当前X, 当前Y, 原件) 时
  如果 全局变量 摇杆激活 = 真 则
    // 计算偏移
    设置 全局变量 偏移X = 当前X - 全局变量 摇杆中心X
    设置 全局变量 偏移Y = 当前Y - 全局变量 摇杆中心Y
    
    // 限制在圆形范围内
    设置 全局变量 距离 = 平方根(全局变量 偏移X ^ 2 + 全局变量 偏移Y ^ 2)
    如果 全局变量 距离 > 全局变量 摇杆半径 则
      设置 全局变量 比例 = 全局变量 摇杆半径 / 全局变量 距离
      设置 全局变量 偏移X = 全局变量 偏移X * 全局变量 比例
      设置 全局变量 偏移Y = 全局变量 偏移Y * 全局变量 比例
    如果结束
    
    // 更新摇杆位置
    设置 ImageSprite_JoyKnob.X = 全局变量 摇杆中心X + 全局变量 偏移X - 25
    设置 ImageSprite_JoyKnob.Y = 全局变量 摇杆中心Y + 全局变量 偏移Y - 25
    
    // 归一化方向(-1到1)
    设置 全局变量 摇杆方向X = 全局变量 偏移X / 全局变量 摇杆半径
    设置 全局变量 摇杆方向Y = 全局变量 偏移Y / 全局变量 摇杆半径
  如果结束

当 Canvas1.触摸结束() 时
  // 摇杆回中
  设置 全局变量 摇杆激活 = 假
  设置 全局变量 摇杆方向X = 0
  设置 全局变量 摇杆方向Y = 0
  设置 ImageSprite_JoyKnob.X = 全局变量 摇杆中心X - 25
  设置 ImageSprite_JoyKnob.Y = 全局变量 摇杆中心Y - 25

当 时钟1.计时 时
  // 根据摇杆方向移动角色
  设置 全局变量 移动速度 = 5
  设置 Player.X = Player.X + 全局变量 摇杆方向X * 全局变量 移动速度
  设置 Player.Y = Player.Y + 全局变量 摇杆方向Y * 全局变量 移动速度

三、图像精灵轨道旋转

初始化全局变量 轨道角度 = 0
初始化全局变量 轨道半径 = 100
初始化全局变量 轨道中心X = 0
初始化全局变量 轨道中心Y = 0
初始化全局变量 旋转速度 = 3  // 每帧旋转度数

当 Screen1.初始化 时
  设置 全局变量 轨道中心X = Canvas1.宽度 / 2
  设置 全局变量 轨道中心Y = Canvas1.高度 / 2
  调用 时钟1.开启定时器(间隔: 30)

当 时钟1.计时 时
  // 更新角度
  设置 全局变量 轨道角度 = (全局变量 轨道角度 + 全局变量 旋转速度) mod 360
  
  // 计算新位置(角度转弧度)
  设置 全局变量 弧度 = 全局变量 轨道角度 * 3.14159 / 180
  设置 全局变量 新X = 全局变量 轨道中心X + 全局变量 轨道半径 * 余弦(全局变量 弧度)
  设置 全局变量 新Y = 全局变量 轨道中心Y + 全局变量 轨道半径 * 正弦(全局变量 弧度)
  
  // 更新精灵位置
  设置 ImageSprite_Planet.X = 全局变量 新X - ImageSprite_Planet.宽度 / 2
  设置 ImageSprite_Planet.Y = 全局变量 新Y - ImageSprite_Planet.高度 / 2
  
  // 精灵自身也旋转
  设置 ImageSprite_Planet.旋转角度 = 全局变量 轨道角度

// 多个卫星轨道
初始化全局变量 卫星列表 = [
  {"精灵": ImageSprite1, "半径": 80, "速度": 2, "角度": 0},
  {"精灵": ImageSprite2, "半径": 130, "速度": 1.5, "角度": 120},
  {"精灵": ImageSprite3, "半径": 180, "速度": 1, "角度": 240}
]

当 时钟1.计时 时
  对于 每个 卫星 在 全局变量 卫星列表 中
    设置 全局变量 角度 = 获取键的值(卫星, "角度", 0) + 获取键的值(卫星, "速度", 1)
    调用 设置键的值(卫星, "角度", 全局变量 角度 mod 360)
    
    设置 全局变量 弧度 = 全局变量 角度 * 3.14159 / 180
    设置 全局变量 半径 = 获取键的值(卫星, "半径", 100)
    设置 全局变量 精灵 = 获取键的值(卫星, "精灵", 空)
    
    设置 全局变量 精灵.X = 全局变量 轨道中心X + 全局变量 半径 * 余弦(全局变量 弧度) - 全局变量 精灵.宽度 / 2
    设置 全局变量 精灵.Y = 全局变量 轨道中心Y + 全局变量 半径 * 正弦(全局变量 弧度) - 全局变量 精灵.高度 / 2
  循环结束

四、PopupMenu动态文字

初始化全局变量 菜单项列表 = ["选项1", "选项2", "选项3"]

// 动态设置菜单文字
过程 更新菜单(新菜单列表)
  设置 全局变量 菜单项列表 = 新菜单列表
过程结束

当 Button_Menu.被点击 时
  // 显示弹出菜单
  调用 Notifier1.显示选择对话框(
    消息: "请选择",
    标题: "菜单",
    按钮1文本: 获取列表项目(全局变量 菜单项列表, 1),
    按钮2文本: 获取列表项目(全局变量 菜单项列表, 2),
    可取消: 真
  )

// 使用ListPicker模拟PopupMenu
当 Button_ShowMenu.被点击 时
  设置 ListPicker1.Elements = 全局变量 菜单项列表
  调用 ListPicker1.Open()

当 ListPicker1.AfterPicking() 时
  设置 全局变量 选中项 = ListPicker1.Selection
  设置 全局变量 选中索引 = ListPicker1.SelectionIndex
  
  // 根据选择执行操作
  如果 全局变量 选中项 = "选项1" 则
    调用 执行操作1()
  否则 如果 全局变量 选中项 = "选项2" 则
    调用 执行操作2()
  如果结束

// 动态更新菜单内容
当 Button_UpdateMenu.被点击 时
  调用 更新菜单(["新选项A", "新选项B", "新选项C", "新选项D"])
  调用 Notifier1.显示消息("菜单已更新")

教程作者:ai2claw 🐝 | 创建时间:2026-03-30

参考资料与版权声明

原文来源

版权声明

本文档基于 MIT App Inventor 官方文档及社区资源整理,版权归原作者所有:
  • MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权
  • MIT App Inventor Community 帖子版权归原作者所有
本文档由 ai2claw 🐝 整理,仅供学习参考,如有侵权请联系删除。