概述
已有文档:sqlite_tutorial.md 介绍了SQLite扩展,dynamic_components.md 介绍了动态创建组件。本文聚焦用表格形式展示数据库内容。
App Inventor没有内置TableView
App Inventor没有原生的表格组件。展示表格数据有以下方案:
| 方案 | 难度 | 排版 | 推荐度 |
|---|---|---|---|
| TableArrangement | ⭐ | 固定行列 | ⭐⭐ |
| 动态创建布局 | ⭐⭐⭐ | 灵活 | ⭐⭐⭐ |
| WebView + HTML表格 | ⭐⭐ | 最好 | ⭐⭐⭐⭐⭐ |
| Table扩展 | ⭐⭐ | 好 | ⭐⭐⭐⭐ |
| ListView | ⭐ | 单列 | ⭐⭐⭐ |
方案一:WebView + HTML表格(推荐)
HTML模板
<!-- table_view.html -->
<style>
table { width:100%; border-collapse:collapse; font-size:14px; }
th { background:#4CAF50; color:white; padding:8px; text-align:left; }
td { padding:8px; border-bottom:1px solid #ddd; }
tr:nth-child(even) { background:#f9f9f9; }
tr:active { background:#e0e0e0; }
</style>
<table id="table">
<thead id="header"></thead>
<tbody id="body"></tbody>
</table>
<script>
setInterval(function(){
var msg = window.AppInventor.getWebViewString();
if(msg && msg !== ""){
try {
var data = JSON.parse(msg);
if(data.cmd === "setData"){
var cols = data.columns;
var rows = data.rows;
document.getElementById('header').innerHTML = '<tr>' + cols.map(function(c){return '<th>'+c+'</th>'}).join('') + '</tr>';
document.getElementById('body').innerHTML = rows.map(function(row, i){
return '<tr onclick="selectRow('+i+')">' + cols.map(function(c){return '<td>'+(row[c]||'')+'</td>'}).join('') + '</tr>';
}).join('');
}
} catch(e) { window.AppInventor.setWebViewString("ERROR:"+e.message); }
}
},100);
function selectRow(i){
window.AppInventor.setWebViewString("SELECT:"+i);
}
</script>
App Inventor积木块
when Screen1.Initialize() {
Web浏览器1.HomeUrl = "file:///android_asset/table_view.html"
SQLite1.OpenDatabase("myapp.db")
}
when 按钮_加载数据.Click() {
SQLite1.QuerySQL("SELECT * FROM users")
}
when SQLite1.QueryResult(结果) {
var 列名 = make_list("id", "name", "phone", "email")
var JSON = join("{\"cmd\":\"setData\",\"columns\":[\"id\",\"name\",\"phone\",\"email\"],\"rows\":", Web1.JsonTextEncode(结果), "}")
Web浏览器1.WebViewString = JSON
}
when Web浏览器1.WebViewStringChange(value) {
if (starts_with(value, "SELECT:")) {
var 行索引 = replace_all(value, "SELECT:", "")
标签_选中.Text = join("选中第", 行索引 + 1, "行")
}
}
方案二:Table扩展
extensions/Table.md 已有文档。基本用法:
when Screen1.Initialize() {
Table1.SetColumnNames(make_list("ID", "姓名", "电话", "邮箱"))
Table1.SetColumnWidths(make_list(50, 120, 120, 180))
}
when 按钮_加载数据.Click() {
SQLite1.QuerySQL("SELECT * FROM users")
}
when SQLite1.QueryResult(结果) {
Table1.ClearData()
var i = 1
while (i <= length_of_list(结果)) {
var 记录 = select_list_item(结果, i)
Table1.AddRow(make_list(
get_dictionary_value("id", 记录),
get_dictionary_value("name", 记录),
get_dictionary_value("phone", 记录),
get_dictionary_value("email", 记录)
))
i = i + 1
}
}
方案三:动态创建布局
参考 dynamic_components.md,使用CompCreator扩展:
when SQLite1.QueryResult(结果) {
// 先清除之前的行
清除表格()
// 创建表头
CompCreator1.CreateLabel(
HorizontalArrangement_表头, "header",
"ID | 姓名 | 电话 | 邮箱", 14, -16777216, true)
// 创建数据行
var i = 1
while (i <= length_of_list(结果)) {
var 记录 = select_list_item(结果, i)
var 显示 = join(get_dictionary_value("id", 记录), " | ",
get_dictionary_value("name", 记录), " | ",
get_dictionary_value("phone", 记录), " | ",
get_dictionary_value("email", 记录))
CompCreator1.CreateLabel(
VerticalArrangement_表格, join("row", i),
显示, 12, -12303292, false)
i = i + 1
}
}
常见问题
Q1: 表格太宽显示不全?
WebView方案可以设置CSS让表格自适应宽度:
table { width:100%; font-size:12px; }
td { word-break:break-all; }
Q2: 数据量大时卡顿?
- 分页查询:
SELECT * FROM users LIMIT 20 OFFSET 0 - 使用WebView方案性能最好
- 避免一次加载上千行
总结
| 方案 | 推荐度 | 性能 | 适用 |
|---|---|---|---|
| WebView + HTML | ⭐⭐⭐⭐⭐ | 好 | 大数据量 |
| Table扩展 | ⭐⭐⭐⭐ | 中 | 中等数据 |
| 动态组件 | ⭐⭐⭐ | 差 | 小数据量 |
扫码添加客服咨询