App Inventor 2 屏幕管理与多屏幕教程

« 返回首页

概述

已有文档:screen_communication.md 介绍了屏幕间传值。本文聚焦屏幕管理、切换顺序和布局问题。

屏幕基本概念

概念 说明
Screen App Inventor的基本页面单元
多Screen 每个Screen是独立的,变量不共享
Screen切换 通过”打开另一个屏幕”和”关闭屏幕”
屏幕栈 切换时形成栈结构

屏幕切换

基本切换

// 从Screen1跳到Screen2
when 按钮_跳转.Click {
  openAnotherScreen("Screen2")
}

// Screen2返回Screen1
when 按钮_返回.Click {
  closeScreen()
}

带参数切换

// 传值跳转
when 按钮_跳转.Click {
  var 起始值 = "来自Screen1的数据"
  openAnotherScreenWithStartValue("Screen2", 起始值)
}

// Screen2接收值
when Screen2.Initialize {
  var 传入值 = getStartValue()
  标签_接收.Text = 传入值
}

// Screen2返回并传值
when 按钮_返回.Click {
  var 返回值 = "来自Screen2的数据"
  closeScreenWithValue(返回值)
}

// Screen1接收返回值
when Screen1.OtherScreenClosed(屏幕名, 返回值) {
  标签_返回.Text = "从" + 屏幕名 + "返回:" + 返回值
}

设置屏幕先后顺序

方法一:Screen名称排序

App Inventor按字母顺序排列Screen列表。可以通过命名控制顺序:

Screen_Main       ' 主页(按字母排在后面)
Screen_A_Login    ' 登录(按字母排在前面)
Screen_B_Register ' 注册
Screen_C_Home     ' 首页

方法二:在代码中控制流程

when Screen1.Initialize {
  // 检查是否已登录
  var 已登录 = 微数据库1.GetValue("logged_in", false)
  if 已登录 {
    openAnotherScreen("Screen_Home")
  } else {
    openAnotherScreen("Screen_Login")
  }
}

方法三:第一个Screen作为引导页

让Screen1只做引导/检查:

when Screen1.Initialize {
  var 首次使用 = 微数据库1.GetValue("first_use", true)
  if 首次使用 {
    openAnotherScreen("Screen_Welcome")
    微数据库1.StoreValue("first_use", false)
  } else {
    openAnotherScreen("Screen_Home")
  }
}

绝对布局兼容性问题

雷电模拟器中标签不显示

用户反馈:”app inventor2绝对布局中的标签在雷电模拟器中无法显示”

原因

  1. 绝对布局已过时:App Inventor已移除TableArrangement的绝对定位
  2. 模拟器兼容性:雷电模拟器的Android版本和分辨率可能与真机不同
  3. 字体大小差异:模拟器的DPI设置不同导致布局偏移

解决方案

❌ 不要使用绝对定位
使用相对布局代替:

✅ 使用VerticalArrangement + HorizontalArrangement
VerticalArrangement1
├── HorizontalArrangement1(顶部栏)
│   ├── 标签_标题
│   └── 按钮_设置
├── 垂直布局_内容(中间内容区)
│   └── 标签_内容
└── HorizontalArrangement2(底部栏)
    └── 按钮_操作
// ✅ 使用自适应属性
Screen1.AlignHorizontal = 3
Screen1.Scrollable = true

模拟器调试建议

  1. 使用真实设备测试
  2. 雷电模拟器设置分辨率与真机一致
  3. 使用MIT App Inventor Companion直接在真机调试
  4. 检查DPI设置(雷电默认DPI可能偏高)

屏幕生命周期

when Screen1.Initialize {
  // 屏幕创建时调用(只调用一次)
  // 适合:初始化组件、加载数据
}

when Screen1.GotFocus {
  // 屏幕获得焦点时调用
  // 适合:刷新数据、恢复状态
}

when Screen1.LostFocus {
  // 屏幕失去焦点时调用
  // 适合:暂停音乐、保存临时数据
}

when Screen1.BackPressed {
  // 用户按返回键时调用
  // 适合:确认退出、保存数据
  var 有未保存数据 = false
  if 有未保存数据 {
    对话框1.ShowChooseDialog("有未保存的数据,确定退出?", "确认", "退出", "取消", false)
  } else {
    closeScreen()
  }
}

多屏幕App性能优化

屏幕数量建议

App Inventor中每个Screen都会增加APK体积和加载时间:

屏幕数 APK大小 建议
1-5 小 ✅ 正常
6-10 中 ⚠️ 可接受
10+ 大 ❌ 考虑虚拟屏幕

使用虚拟屏幕替代多屏幕

参考 virtual_screen.md:用一个Screen + 多个布局模拟多屏幕:

when 按钮_首页.Click() {
  垂直布局_首页.Visible = true
  垂直布局_设置.Visible = false
  垂直布局_关于.Visible = false
}
when 按钮_设置.Click() {
  垂直布局_首页.Visible = false
  垂直布局_设置.Visible = true
  垂直布局_关于.Visible = false
}

常见问题

Q1: 切换屏幕时闪黑?

App Inventor切换屏幕时有短暂黑屏。优化:

  • 使用虚拟屏幕代替真实屏幕切换
  • 在新Screen的Initialize中设置背景色

Q2: 全局变量在Screen间共享?

不能。 每个Screen有独立的作用域。解决方案:

  • TinyDB存储共享数据
  • 通过起始值/返回值传递

Q3: 屏幕切换很慢?

  • 减少每个Screen的组件数量
  • 使用虚拟屏幕
  • 图片资源压缩

总结

需求 方案
控制屏幕顺序 代码逻辑控制,不依赖字母排序
屏幕间传值 起始值/返回值 + TinyDB
布局兼容 避免绝对布局,用相对布局
减少屏幕数 虚拟屏幕方案
文档反馈