美文网首页
LibGdx 游戏开发之TableLayout

LibGdx 游戏开发之TableLayout

作者: imagefancy | 来源:发表于2017-12-25 01:16 被阅读0次

    https://github.com/EsotericSoftware/tablelayout

    Please use the TableLayout discussion group for support.

    Overview 概述

    TableLayout是一个轻量级的Java库,它和HTML的table类似。可以利用logical table来设置UI widget的位置尺寸
    TableLayout的核心是UI toolkit agnostic,支持 libgdx, Swing, Android, and TWL。使用table的layout非常直观,而且TableLayout's JAVA API非常好用。

    快速开始

    下面是libgdx中一个简单例子:

        // Keep your code clean by creating widgets separate from layout.
        Label nameLabel = new Label("Name:", skin);
        TextField nameText = new TextField(skin);
        Label addressLabel = new Label("Address:", skin);
        TextField addressText = new TextField(skin);
    
        Table table = new Table();
        table.add(nameLabel);              // Row 0, column 0.
        table.add(nameText).width(100);    // Row 0, column 1.
        table.row();                       // Move to next row.
        table.add(addressLabel);           // Row 1, column 0.
        table.add(addressText).width(100); // Row 1, column 1.
    

    上面的代码增加了2行2列一共4个单元格。add方法返回1个cell, cell有控制layout的方法。在例子中text fields的宽度被设置为100.
    本文档中使用的示例代码是针对libgdx的,但其他支持的工具包的API几乎完全相同

    image.png

    Root table 根表

    当进行UI布局的时候,UI widget并不设置它自己的尺寸,它只是提供minimun,preferredmaximum三种选项。widget的父元素使用其自身的尺寸和这三种选项,来对widget进行尺寸设置。许多布局会使用单个固定尺寸(通常为整个屏幕)的table作为根表.widgets和内部表被加入到根表中。
    每种UI toolkit都有不同的设定根表尺寸的方法,例如:在Swing中需要把table加入JFrame‘s的内容面板;在libgdx中用setFillParent方法:

        Table table = new Table();
        table.setFillParent(true);
        stage.addActor(table);
    

    Debugging 调试

    TableLayout可以画出调试线,用于视觉化。Debugging通过在table上调用debug方法来开启。如果debugging开启了,Libgdx可以自动渲染调试线。其他的UI toolkits可能需要调用函数去渲染调试线。

        table.debug();      // Turn on all debug lines (table, cell, and widget).
        table.debugTable(); // Turn on only table lines.
    

    Adding cells 增加单元格

    Widgets通过add方法来加入到表格(对于已经有add方法的UI toolkits,那么将使用addcell方法)。这个方法将在此行中增加1个单元格。如果要增加下一行,则调用row方法。

        table.add(nameLabel);    // Row 0, column 0.
        table.add(nameText);     // Row 0, column 1. 
        table.row();             // Move to next row.
        table.add(addressLabel); // Row 1, column 0.
        table.add(addressText);  // Row 1, column 1.
    

    add方法返回一个Cell,Cell有一些属性可以控制布局。Cell的每个方法的返回值都是Cell,允许链式调用。

        table.add(nameText).padLeft(10).width(100); // Sets left padding and width on the new cell.
    

    Logical table 逻辑表

    这些Cells组成了一个逻辑表,但是逻辑表的大小和table的尺寸是不一样的。

    image.png

    外面的蓝色矩形展示了table widget的尺寸。里面的蓝色矩形展示了逻辑表的尺寸,且默认居中对齐。对齐方式可以通过table的函数去设置。table函数反馈值为table,所以也可以像cell的方法一样进行链式调用。

        table.right().bottom();
    
    image.png

    Cell properties 单元格属性

    Expand 扩展

    为了使得逻辑表占据table的全部,TableLayber需要被告知那些cells会占用到额外的空间。

        table.add(nameLabel).expandX(); // Column 0 receives all extra horizontal space.
        table.add(nameText).width(100);
        table.row();
        table.add(addressLabel);
        table.add(addressText).width(100);
    
    image.png

    红线表示单元格边界,绿线表示widget的边界。注意左边列占据了X轴上横向空间。只需要有1个单元格被扩展,就可以占用整行或者整列的额外空间。如果多列被扩展,那么额外的空间就会均匀分布。

        table.add(nameLabel).expandX();           // Receives extra horizontal space.
        table.add(nameText).width(100).expandX(); // Also receives extra horizontal space.
        table.row();
        table.add(addressLabel);
        table.add(addressText).width(100);
    
    image.png

    见下图: Expand在Y轴同样适用,相应函数是expandYexpand方法则是在X和Y轴上都进行扩展。

        table.add(nameLabel).expand();     // Receives all extra horizontal and vertical space.
        table.add(nameText).width(100);
        table.row();
        table.add(addressLabel);
        table.add(addressText).width(100);
    
    image.png

    Alignment 对齐

    与对齐逻辑表类似,widget在单元格里面也能做对齐。

        table.add(nameLabel).expand().bottom().right(); // Aligned bottom right.
        table.add(nameText).width(100).top();           // Aligned top.
        table.row();
        table.add(addressLabel);
        table.add(addressText).width(100);
    
    image.png

    Fill 填充

    fill方法使得widget的尺寸调整到单元格的尺寸。同expand类似,有fillXfillY两种方法。

        table.add(nameLabel).expand().bottom().fillX(); // Sized to cell horizontally.
        table.add(nameText).width(100).top();
        table.row();
        table.add(addressLabel);
        table.add(addressText).width(100);
    
    image.png

    请注意,红色单元格线是在绿色小部件行的顶部绘制的。

    Widget size Widget的尺寸

    默认情况下,attempt将widgets的尺寸调整到它们的preferred size。如果widget不能适配,它们的尺寸将被调整到preferred sizeminimum size之间,具有较大首选尺寸的小部件,将获得更多空间。
    如果widgets的minimum size都不能使用,那么布局被破坏,widgets可能重叠。 “fill”方法不会使widgets大于widgets的最大尺寸。

    不应将Widgets改为preferredminimum或'maximum'。 相反,这些size可以在cell上进行设置,并将用来代替widgets的size。

        table.add(nameLabel);
        table.add(nameText).minWidth(100);     // Sets min width.
        table.row();
        table.add(addressLabel);
        table.add(addressText).prefWidth(999); // Sets pref width.
    
    image.png

    这里的“prefWidth”是999,比table还是大,因此它的大小将自动调整`。

    width 方法可以快捷的设置 minWidth, prefWidth, 和 maxWidth为相同的值. height 方法可以快捷的设置 minHeight, prefHeight, 和 maxHeight为相同的值. size 方法需要widthheight,且设置所有6个属性.

    Padding 填充

    padding是指单元格边缘的额外空间。

        table.add(nameLabel);
        table.add(nameText).width(100).padBottom(10); // Sets bottom padding.
        table.row();
        table.add(addressLabel);
        table.add(addressText).width(100).pad(10);    // Sets top, left, bottom, right padding.
    
    image.png
    请注意:单元格之间的padding,所以文本字段之间有20个像素。 调试线不一定显示paddning来自哪个单元格,因为它对于表格的布局并不重要。
    填充也可以应用到table的边缘。
        table.pad(10);
    

    Spacing

    和padding类似,spacing是cell边的额外空间。但是cells之间的spacing不会联合,相反,较大的一个spacing会被使用。另外,spacing不适用于table. spacing使得cells之间的一致的空间变得容易。

        table.add(nameLabel);
        table.add(nameText).width(100).spaceBottom(10); // Sets bottom spacing.
        table.row();
        table.add(addressLabel);
        table.add(addressText).width(100).space(10);    // Sets top, left, bottom, right spacing.
    
    image.png

    注意:cells之间的spacing不会融合,所有在text fildes之间有10 pixels. 另外注意在text field的低部没有spcing,因为spacing不适用于table的边界。

    Colspan

    一个cell可以span多列(就是合并)。

        table.add(nameLabel);
        table.add(nameText).width(100).spaceBottom(10);
        table.row();
        table.add(addressLabel).colspan(2);             // Spans 2 columns.
    
    image.png

    注意: 不能合并多个行。但是可以用嵌套表格达到此目的。

    Uniform 统一

    单元格设置uniform后,单元格的尺寸都变成统一的。
    Cells with uniform set to true will be the same size.

        table.add(nameLabel).uniform();           // These two cells will have
        table.add(nameText).width(100).uniform(); // the same width and height.
        table.row();
        table.add(addressLabel);
        table.add(addressText).width(100);
    
    image.png

    Defaults 默认

    Cell defaults 单元格默认

    一般来说,单元格设计时一般采用相同的属性,所有给所有单元设置一个默认的属性会大大减少布局的工作量。table的defaults方法返回一个单元格,这个单元格的属性将被应用到所有的单元格。

        table.defaults().width(100); // Sets defaults for all cells.
        table.add(nameLabel);
        table.add(nameText);
        table.row();
        table.add(addressLabel);
        table.add(addressText);
    
    image.png

    Column defaults 列默认

    table的columnDefaults方法返回一个单元格,这个单元格的属性将应用于此单元格所在的列的所有单元格。通过方法设置的属性将覆盖单元格的默认属性。列的索引从0开始。

        table.columnDefaults(1).width(150); // Sets defaults for cells in column 0.
        table.add(nameLabel);
        table.add(nameText);
        table.row();
        table.add(addressLabel);
        table.add(addressText);
    
    image.png

    Row defaults 行默认

    当row方法调用时,会返回一个单元格,这个单元格的属性将被应用到其所在行的所有单元格。通过此方法设置的属性将会覆盖单元格的默认属性和列的默认属性。row方法在增加单元格之前就可以调用,这就使得第一行就可以用默认的属性。

        table.row().height(50);  // Set cell defaults for row 0.
        table.add(nameLabel);
        table.add(nameText);
        table.row().height(100); // Set cell defaults for row 1.
        table.add(addressLabel);
        table.add(addressText);
    
    image.png

    Stacks 堆栈

    stack widget是一种特殊类型的容器,它将每个child设置为stack的大小。当需要将widgets堆叠在一起时,这非常有用。 添加到stack的第一个widget绘制在底部,添加的最后一个widget绘制在顶部。

    Similar libraries

    A few Java, table-based layout managers:

    GridBagLayout can handle complex table-based layouts, but does so via a clunky API.

    TableLayout (the other one) uses 2D arrays of percentages, sizes, and flags to describe the table and how it should be sized. This approach has the same problems as GridBagLayout.

    PageLayout uses a concise Java API to describe the table.

    PnutsLayout (webpage no longer available) was written by Toyokazu Tomatsu as part of Pnuts. TableLayout was originally inspired by PnutsLayout.

    UIHierarchy was also inspired by PnutsLayout. It is interesting because it is not actually a layout manager, instead it uses a combination of method chaining and constraint strings to more cleanly create UI hierarchies and configure layout parameters.

    RiverLayout uses tags in constraint strings.

    FormLayout is similar to RiverLayout, but more sophisticated.

    MIGLayout is even more sophisticated than FormLayout. It attempts to support many kinds of layouts beyond tables and has a somewhat bloated number of features. It has a complex constraint language. It can layout using a grid, border, absolute, etc.

    DesignGridLayout uses canonical grids. For the most part, widgets are simply added and the ideal table is determined automatically. This cuts down the needed Java code to a minimum and enforces UI guidelines. The downside is that DesignGridLayout does not handle arbitrary table layouts. If a UI problem can be handled using a canonical grid, DesignGridLayout is the most elegant solution. If you want to deviate from a canonical grid, you have no recourse.

    Please feel free to submit additional libraries to be included in this section or suggest better descriptions.

    相关文章

      网友评论

          本文标题:LibGdx 游戏开发之TableLayout

          本文链接:https://www.haomeiwen.com/subject/zgocgxtx.html