Libgdx网格布局

可直接用于libgdx项目中的布局类(可直接复制进项目使用),支持定制行列宽,支持表格嵌套,支持单元格元素居中/左对齐,支持整体显示和隐藏的切换

import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;

import java.util.LinkedList;

public class GridLayout {
    // 舞台元素
    private Actor[][] actors;
    // 行数,列数
    private int row;
    private int column;
    // 行高,列宽
    private float[] rowHeights;
    private float[] columnWidths;
    // 坐标
    private float x;
    private float y;
    // 居中对齐
    private boolean center;
    // 网格们
    private LinkedList<GridLayout> grids = new LinkedList<>();
    // layout的宽高
    private float width;
    private float height;
    // 是否可见
    private boolean visible;
    
    /**
     * 构造布局
     * @param row         行数
     * @param column      列数
     * @param x           网格开始坐标x
     * @param y           网格开始坐标y
     * @param rowHeight   行高
     * @param columnWidth 列宽
     * @param center      每格剧中布局? true/false
     */
    public GridLayout(int row, int column, float x, float y, float rowHeight, float columnWidth, boolean center) {
        this.center = center;
        this.row = row;
        this.column = column;
        this.x = x;
        this.y = y;
        actors = new Actor[row][column];
        rowHeights = new float[row];
        columnWidths = new float[column];
        for (int i = 0; i < row; i++) {
            rowHeights[i] = rowHeight;
        }
        for (int i = 0; i < column; i++) {
            columnWidths[i] = columnWidth;
        }
        width = columnWidth * column;
        height = rowHeight * row;
        visible=true;
    }

    /**
     * 布局到舞台
     * 调用此方法实现布局
     * @param stage 舞台
     */
    public void layout(Stage stage) {
        for (int i = 0; i < row; i++) {
            float alHeight = y;
            for (int h = 0; h < i; h++) {
                alHeight += rowHeights[h];
            }
            for (int j = 0; j < column; j++) {
                if (actors[i][j] == null) continue;
                float alWidth = x;
                for (int w = 0; w < j; w++) {
                    alWidth += columnWidths[w];
                }
                if (center) {
                    actors[i][j].setPosition(
                            alWidth + (columnWidths[j] - actors[i][j].getWidth()) / 2,
                            alHeight + (rowHeights[i] - actors[i][j].getHeight()) / 2
                    );
                } else {
                    actors[i][j].setPosition(alWidth, alHeight);
                }
            }
        }
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                if (actors[i][j] == null) {
                    continue;
                }
                stage.addActor(actors[i][j]);
            }
        }
        for (GridLayout grid : grids) {
            grid.layout(stage);
        }
    }

    /**
     * 通过Actor数组添加元素,元素数量不得超过row * column,从左下到右上添加(和libgdx布局方式保持一致)
     * @param actorArray Actor数组
     */
    public void pushActors(Actor[] actorArray) {
        if (actorArray.length > row * column) {
            throw new ArrayIndexOutOfBoundsException("元素数量超出网格布局最大限制");
        } else {
            int index = 0;
            for (int i = 0; i < row; i++) {
                if (index >= actorArray.length) {
                    break;
                }
                for (int j = 0; j < column; j++) {
                    actors[i][j] = actorArray[index];
                    if (++index > actorArray.length) {
                        break;
                    }
                }
            }
        }
    }

    /**
     * 在网格中添加网格
     * @param rowIndex
     * @param columnIndex
     */
    public void addElement(GridLayout grid, int rowIndex, int columnIndex) {
        float alWidth = x;
        for (int i = 0; i < columnIndex; i++) {
            alWidth += columnWidths[i];
        }
        float alHeight = y;
        for (int i = 0; i < rowIndex; i++) {
            alHeight += rowHeights[i];
        }
        grid.setLocation(alWidth, alHeight);
        grids.add(grid);
    }

    /**
     * 在网格的指定位置添加元素
     * @param rowIndex
     * @param columnIndex
     */
    public void addElement(Actor actor, int rowIndex, int columnIndex) {
        actors[rowIndex][columnIndex] = actor;
    }

    /**
     * 自定义列宽
     * @param columnIndex 列index (从0开始)
     * @param width       设置的宽度
     */
    public void setWidth(int columnIndex, float width) {
        columnWidths[columnIndex] = width;
    }

    /**
     * 自定义行高
     * @param rowIndex 行index (从0开始)
     * @param height   设置的高度
     */
    public void setHeight(int rowIndex, float height) {
        rowHeights[rowIndex] = height;
    }

    /**
     * 设置坐标
     * @param x
     * @param y
     */
    public void setLocation(float x, float y) {
        this.x = x;
        this.y = y;
    }

    /**
     * 更改居中
     * @param center 居中否
     */
    public void setCenter(boolean center) {
        this.center = center;
    }

    public float getWidth() {
        return width;
    }

    public float getHeight() {
        return height;
    }

    public float getX() {
        return this.x;
    }

    public float getY() {
        return this.y;
    }

    /**
     * grid居中于指定舞台
     * @param stage
     */
    public void moveToCenter(Stage stage) {
        float gridX;
        float gridY;
        gridX = (stage.getWidth() - getWidth()) / 2;
        gridY = (stage.getHeight() - getHeight()) / 2;
        setLocation(gridX, gridY);
    }

    /**
     * 用于显示整个layout的元素
     * @param stage layout所在的stage
     */
    public void show(Stage stage){
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                if (actors[i][j]!=null){
                    stage.addActor(actors[i][j]);
                }
            }
        }
        for(GridLayout grid:grids){
            grid.show(stage);
        }
        visible = true;
    }

    /**
     * 用于隐藏整个layout的元素
     * @param stage layout所在的stage
     */
    public void hide(Stage stage){
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                if (actors[i][j]!=null){
                    stage.getRoot().removeActor(actors[i][j]);
                }
            }
        }
        for(GridLayout grid:grids){
            grid.hide(stage);
        }
        visible = false;
    }

    /**
     * 查看该layout是否处于可见状态
     * @return boolean true/false 可见/隐藏
     */
    public boolean isVisible(){
        return visible;
    }

    /**
     * 设置可见(不是隐藏用的方法)不推荐使用!!!
     * 使用show()和hide()方法控制表格布局的显示和隐藏,不要使用此方法!!!
     * @param visible boolean true/false
     */
    public void setVisible(boolean visible) {
        this.visible = visible;
    }
}

使用demo(仅供参考,非完整可运行程序):

// 设置button样式
upTexture = new Texture(Gdx.files.internal("but1.png"));
downTexture = new Texture(Gdx.files.internal("but2.png"));
Button.ButtonStyle style = new Button.ButtonStyle();
style.up = new TextureRegionDrawable(new TextureRegion(upTexture));
style.down = new TextureRegionDrawable(new TextureRegion(downTexture));

// 声明网格布局4行3列
grid1 = new GridLayout(4,3,0,0,100,100,false);

buttons[0] = new Button(style);
buttons[0].addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.app.log(TAG,"1按钮被点击了");
    }
});
buttons[0].setSize(100,100);
buttons[1] = new Button(style);
buttons[1].addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.app.log(TAG,"2按钮被点击了");
    }
});
buttons[1].setSize(100,100);
buttons[2] = new Button(style);
buttons[2].addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.app.log(TAG,"3按钮被点击了");
    }
});
buttons[2].setSize(100,100);
buttons[3] = new Button(style);
buttons[3].addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.app.log(TAG,"4按钮被点击了");
    }
});
buttons[3].setSize(100,100);
buttons[4] = new Button(style);
buttons[4].addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.app.log(TAG,"5按钮被点击了");
    }
});
buttons[4].setSize(100,100);
buttons[5] = new Button(style);
buttons[5].addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.app.log(TAG,"6按钮被点击了");
    }
});
buttons[5].setSize(100,100);
buttons[6] = new Button(style);
buttons[6].addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.app.log(TAG,"7按钮被点击了");
    }
});
buttons[6].setSize(100,100);
buttons[7] = new Button(style);
buttons[7].addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.app.log(TAG,"8按钮被点击了");
    }
});
buttons[7].setSize(100,100);
buttons[8] = new Button(style);
buttons[8].addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.app.log(TAG,"9按钮被点击了");
    }
});
buttons[8].setSize(100,100);

button3 = new Button(style);
button3.addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.app.log(TAG,"666按钮被点击了");
    }
});
button3.setSize(100,100);
// 控制开关(点击此按钮控制整个GridLayout的显示和隐藏)
Button button4 = new Button(style);
button4.addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        if(grid1.isVisible()){
            grid1.hide(stage);
        }else{
            grid1.show(stage);
        }
    }
});
button4.setSize(100,100);
button4.setPosition(1000,300);
stage.addActor(button4);

// 再建立3个按钮
for(int i=0;i<3;i++){
    buttons2[i] = new Button(style);
    buttons2[i].addListener(new ClickListener() {
        @Override
        public void clicked(InputEvent event, float x, float y) {
            Gdx.app.log(TAG,"按钮被点击了");
        }
    });
    buttons2[i].setSize(100,100);
}
// 设置第二个网格布局,展示嵌套使用
GridLayout grid2 = new GridLayout(1,3,0,0,100,100,false);
grid2.pushActors(buttons2);

grid1.pushActors(buttons);
// 可以灵活改变表格宽高
grid1.setWidth(1, 300);
grid1.addElement(grid2,3,1);
grid1.addElement(button3,3,0);
grid1.layout(stage);

效果图:
在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值