如何让RexUI中的嵌套Sizer可滚动?附代码报错求助
嵌套Sizer滚动面板实现与GridTable报错修复
一、嵌套Sizer转为可滚动面板
原嵌套Sizer代码(来自winner_joiner)
create() { this.dialog; var x = 1200, y = 1600, minWidth = 300, minHeight = undefined, table = { title: "Title/Title/Title", data: [ { name: "AAA", content: "Hello", }, { // icon1: this.add.image(1200, 1600, "btnStorage").setScale(2), // icon2: this.add.image(1300, 1600, "btnStorage").setScale(2), name: "BBBB", content: "World", }, ], }; var sizer = getTable(this, x, y, minWidth, minHeight, table); sizer.drawBounds(this.add.graphics(), 0xff0000); } } var getRow = function (scene, data) { var icon1 = scene.add.image(0, 0, "btnStorage").setScale(2); var icon2 = scene.add.image(0, 0, "btnStorage").setScale(2); var nameLabel = scene.add.text(0, 0, "ngu1", { fontSize: "50px", color: "white", }); var contentLabel = scene.add.text(0, 0, "ngu2", { fontSize: "50px", color: "white", }); var sizer = scene.rexUI.add .sizer({ orientation: "x", }) .add(icon1) .add(icon2) .add(nameLabel, 2, "left") .add(contentLabel, 5, "left"); return sizer; }; var getTable = function (scene, x, y, width, height, table) { var title = scene.add.text(0, 0, table.title, { fontSize: "60px", color: "white", }); var sizer = scene.rexUI.add .sizer(x, y, width, height, { orientation: "y", }) .add(title); var padding = { top: 10, //bottom: 10, left: 10, right: 10, }; var data = table.data; for (var i = 0, cnt = data.length; i < 10; i++) { sizer.add(getRow(scene, data[i]), 0, "left", padding); } sizer.layout(); return sizer; };
实现滚动面板的解决方案
把嵌套Sizer放进ScrollablePanel即可实现滚动,核心是将垂直嵌套Sizer作为面板的内容容器,同时设置固定可视区域尺寸。修改后的代码示例:
create() { this.dialog; var x = 1200, y = 1600, panelWidth = 800, // 面板可视宽度 panelHeight = 1000, // 面板可视高度 table = { title: "Title/Title/Title", data: [ { name: "AAA", content: "Hello" }, { name: "BBBB", content: "World" }, // 多添加测试数据验证滚动效果 { name: "CCC", content: "Test1" }, { name: "DDD", content: "Test2" }, { name: "EEE", content: "Test3" }, { name: "FFF", content: "Test4" }, { name: "GGG", content: "Test5" }, { name: "HHH", content: "Test6" }, ], }; // 创建表格sizer(移除原getTable的x/y参数,由面板管理位置) var tableSizer = getTable(this, undefined, undefined, undefined, undefined, table); // 创建ScrollablePanel并传入表格sizer作为内容 var scrollPanel = this.rexUI.add.scrollablePanel({ x: x, y: y, width: panelWidth, height: panelHeight, scrollMode: 'vertical', // 开启垂直滚动 background: this.add.rectangle(0,0, panelWidth, panelHeight, 0x222222), // 可选背景 content: tableSizer, slider: { track: this.add.rectangle(0,0, 20, panelHeight, 0x555555), thumb: this.add.rectangle(0,0, 20, 100, 0x888888) }, space: { left: 10, right: 10, top: 10, bottom: 10, content: 10, rightSlider: 5 } }) .layout(); // 给面板添加边框可视化 scrollPanel.drawBounds(this.add.graphics(), 0xff0000); } // 调整getTable函数,移除x/y参数,让面板自动管理布局 var getTable = function (scene, _, __, width, height, table) { var title = scene.add.text(0, 0, table.title, { fontSize: "60px", color: "white", }); var sizer = scene.rexUI.add .sizer({ orientation: "y", width: width, // 限制内容宽度与面板一致 height: height }) .add(title); var padding = { top: 10, left: 10, right: 10, bottom: 10 }; var data = table.data; // 遍历实际数据长度,替换原写死的i<10逻辑 for (var i = 0, cnt = data.length; i < cnt; i++) { sizer.add(getRow(scene, data[i]), 0, "left", padding); } sizer.layout(); return sizer; };
核心逻辑:
ScrollablePanel会自动检测内容容器高度,超过面板可视高度时启用滚动。- 确保内容sizer的宽度与面板匹配,避免横向溢出。
- 修正原代码中写死循环次数的问题,改为遍历实际数据长度。
二、GridTable报错:addTableOXY is not a function修复
原报错代码
const setupTable = () => { this.table = this.add.rexGridTable(2900, 1500, 3500, 1700, { scrollMode: "vertical", cellHeight: 500, cellWidth: undefined, cellsCount: this.mergedInfo.length, columns: 6, cellVisibleCallback: onCellVisible.bind(this), }); this.add.graphics().strokeRectShape(this.table.getBounds()); this.table.setInteractive().setVisible(false); this.table.on("pointermove", function (pointer) { if (!pointer.isDown) { return; } var dx = pointer.x - pointer.prevPosition.x; var dy = pointer.y - pointer.prevPosition.y; this.table.addTableOXY(dx, dy).updateTable(); }); return this.table; }; this.table = setupTable();
修复方案
addTableOXY不是RexUI GridTable的内置方法,改用setTableOXY或scrollTo实现拖拽滚动:
const setupTable = () => { this.table = this.add.rexGridTable(2900, 1500, 3500, 1700, { scrollMode: "vertical", cellHeight: 500, cellWidth: undefined, cellsCount: this.mergedInfo.length, columns: 6, cellVisibleCallback: onCellVisible.bind(this), }); this.add.graphics().strokeRectShape(this.table.getBounds()); this.table.setInteractive().setVisible(false); // 修复拖拽滚动逻辑 this.table.on("pointermove", function (pointer) { if (!pointer.isDown) { return; } var dx = pointer.x - pointer.prevPosition.x; var dy = pointer.y - pointer.prevPosition.y; // 方式1:直接修改偏移量后更新表格 const currentOXY = this.table.tableOXY; this.table.setTableOXY(currentOXY.x + dx, currentOXY.y + dy); this.table.updateTable(); // 方式2:用scrollTo(更推荐,自动处理滚动边界) // this.table.scrollTo(currentOXY.x + dx, currentOXY.y + dy); }, this); // 绑定this,确保回调内可访问this.table return this.table; }; this.table = setupTable();
关键修正点:
- 移除不存在的
addTableOXY,改用setTableOXY修改偏移量后调用updateTable,或直接使用scrollTo(后者会自动限制滚动范围,避免内容溢出)。 - 事件回调需绑定
this(通过第三个参数传递),否则内部this.table会指向事件对象而非表格实例。
内容的提问来源于stack exchange,提问作者Nguyễn Hải Long
相关产品推荐
相关产品推荐

