You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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();

关键修正点:

  1. 移除不存在的addTableOXY,改用setTableOXY修改偏移量后调用updateTable,或直接使用scrollTo(后者会自动限制滚动范围,避免内容溢出)。
  2. 事件回调需绑定this(通过第三个参数传递),否则内部this.table会指向事件对象而非表格实例。

内容的提问来源于stack exchange,提问作者Nguyễn Hải Long

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 08:55:55