06.06 布局-GridLayout

2021/5/23 Android 开发基础

GridLayout (网格布局),Android 4.0 后推出的,将其子级放置在矩形网格中的布局。与 TableLayout(表格布局)有点类似,但是功能更多,相对可用性也更高。

主要的特性:

  • 可以设置布局中组件的排列方式。
  • 可以自定义网格布局有多少行,多少列。
  • 可以直接设置组件位于某行某列。
  • 可以设置组件横跨几行或者几列。

# 特性介绍

网格布局由一组无限细的线组成,这些细线将可视区域划分为多个单元。在整个 API 中,网格线由网格索引引用。具有N列的网格具有N+1个从 0 到 N(含)的网格索引。无论如何配置 GridLayout,网格索引0都固定在容器的前边缘,而网格索引N则固定在其后边缘(在考虑填充之后)。

行和列规格

子项占据一个或多个连续的单元,这由它们的rowSpeccolumnSpec布局参数定义。每个规范都定义了要占用的行或列的集合。以及应该如何在生成的单元格组中对齐子元素。尽管单元格通常不会在 GridLayout中 重叠,但是 GridLayout 不会阻止将子级定义为占据相同的单元格或单元格组。但是,在这种情况下,不能保证子代在布局操作完成后不会重叠。

默认单元分配

如果一个子元素不指定希望占据单元格的行和列索引,GridLayout 使用其orientationrowCountcolumnCount属性自动指定单元格位置。

空间

子级之间的空间可以通过使用专用空间视图的实例或通过设置leftMargintopMarginrightMarginbottomMargin布局参数来指定。useDefaultMargins 设置该属性后,将根据平台的主流 UI 样式指南自动分配子级周围的默认边距。如此定义的每个边距都可以通过分配适当的布局参数来独立地覆盖。默认值通常会在组件之间产生合理的间距,但默认值可能会在平台的不同版本之间发生变化。

多余的空间分布

从 API 21开始,GridLayout 的剩余空间分布符合重量原则。如果未指定权重,则遵循先前的约定,并且如果列和行的视图在其组内指定某种形式的对齐方式,则将其视为灵活的。

因此,视图的灵活性受其对齐方式的影响,对齐方式通常通过设置layout_gravity子级布局参数的属性来定义 。如果沿给定的定义了权重对齐方式,则该组件将在该方向上具有柔韧性。如果未设置权重或对齐方式,则假定该组件不灵活

同一行或列组中的多个组件被认为是并行运行的。仅当其中的所有组件都是灵活的时,这样的组才是灵活的。位于公共边界两侧的行和列组将被视为串联操作。如果这两个元素之一组成的复合组是柔性的,则该复合组是柔性的。

要使列拉伸,请确保其中的所有组件都定义了权重或重力。若要防止列拉伸,请确保列中的某个组件未定义weightgravity

当灵活性原则不能完全消除歧义时,GridLayout 的算法倾向于更接近其右边缘和下边缘的行和列。更准确地说,GridLayout 将其每个布局参数视为一组变量中的约束,这些变量定义了沿给定轴的网格线。在布局过程中,GridLayout 解决约束,以便将唯一的解决方案返回到所有变量小于或等于任何其他有效解决方案中相应值的约束。

布局中GONE属性组件的含义

出于布局目的,GridLayout 将 visibility 状态为gone的视图视为具有零宽度和零高度的组件。这与忽略被标记为完全消失的视图的策略有着微妙的区别。例如,如果一个已标记的视图在一列中是单独的,则当且仅当视图上未定义重力时,该列将自身折叠为零宽度。如果定义了重力,则已标记的视图对布局没有影响,容器的布局应与从未添加视图一样。在多余的空间分布期间,过去的视图被认为是零权重的。

这些语句同样适用于行和列,以及行或列的组。

有关 GridLayout 使用的布局参数的完整描述,请参见 GridLayout.LayoutParams (opens new window)

# 相关属性

全局属性(GridLayout的属性)

  • orientation:设置排列方式,vertical(垂直方向,默认属性),horizontal(水平方向)。
  • rowCount:设置布局的行数。
  • columnCount:设置布局的列数。

局部属性(GridLayout的内部组件属性)

  • layout_row:指定组件所在的位置,索引位置从 0 开始。
  • layout_column:指定组件所在的位置,索引位置从 0 开始。
  • layout_rowSpan:设置占用几行空间。
  • layout_columnSpan:设置占用几列空间。

如果需要了解 GridLayout 的更多属性,请参考官方API (opens new window)

网格布局中在可以不指定 layout_widthlayout_heigh 属性,可以自适应内容的网格大小。设置组件横跨几行或者几列后,可以根据需要设置一个填充属性:android:layout_gravity = "fill"

如:layout_gravity="fill",android:layout_rowSpan="2", 表示在水平方向上填充组件所占用的 2 行空间。

理解示意图:

网格布局示意图

# 示例代码

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:rowCount="5"
    android:columnCount="4"
    android:orientation="horizontal">

    <Button android:text="1" />

    <Button android:text="2" />

    <Button android:text="3" />

    <Button
        android:layout_row="1"
        android:background="#2196F3"
        android:text="4" />

    <Button
        android:layout_column="3"
        android:background="#FF5722"
        android:text="5" />

    <Button
        android:layout_rowSpan="2"
        android:layout_gravity="fill"
        android:background="#FFC107"
        android:text="6" />

    <Button
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:background="#E91E63"
        android:text="7" />

    <Button android:text="8" />

    <Button android:text="9" />

    <Button
        android:visibility="gone"
        android:text="10" />

    <Button android:text="11" />

</GridLayout>

# 示例效果

网格布局效果图

通过本节知道网格布局是矩形网格的一种布局,常用于需要网格化布局显示的场景,如:在线商城商品的展示布局场景。