概述
已有文档: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绝对布局中的标签在雷电模拟器中无法显示”
原因
- 绝对布局已过时:App Inventor已移除TableArrangement的绝对定位
- 模拟器兼容性:雷电模拟器的Android版本和分辨率可能与真机不同
- 字体大小差异:模拟器的DPI设置不同导致布局偏移
解决方案
❌ 不要使用绝对定位
使用相对布局代替:
✅ 使用VerticalArrangement + HorizontalArrangement
VerticalArrangement1
├── HorizontalArrangement1(顶部栏)
│ ├── 标签_标题
│ └── 按钮_设置
├── 垂直布局_内容(中间内容区)
│ └── 标签_内容
└── HorizontalArrangement2(底部栏)
└── 按钮_操作
// ✅ 使用自适应属性
Screen1.AlignHorizontal = 3
Screen1.Scrollable = true
模拟器调试建议
- 使用真实设备测试
- 雷电模拟器设置分辨率与真机一致
- 使用MIT App Inventor Companion直接在真机调试
- 检查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 |
| 布局兼容 | 避免绝对布局,用相对布局 |
| 减少屏幕数 | 虚拟屏幕方案 |
扫码添加客服咨询