美文网首页高级UI
FrameLayout、AbsoluteLayout、Table

FrameLayout、AbsoluteLayout、Table

作者: ImWiki | 来源:发表于2019-07-28 11:11 被阅读0次

Android SDK中有6个基础的布局方式,日常的开发中也基本围绕着这6个布局,他们都是ViewGroup的子类,其中TableLayout是的LinearLayout的子类。

  1. LinearLayout 线性布局
  2. RelativeLayout 相对布局
  3. FrameLayout 帧布局、框架布局
  4. AbsoluteLayout 绝对布局
  5. TableLayout 表格布局
  6. GridLayout 网格布局

FrameLayout 帧布局、框架布局

查看android-sdk/platforms/android-28/data/res/values/attrs.xml

    <declare-styleable name="FrameLayout_Layout">
        <attr name="layout_gravity" />
    </declare-styleable>

可以看到,FrameLayout没有自己的属性,而子控件也仅仅有layout_gravity一个,FrameLayout的大小是以子控件最大的大小为准,这个属性可以解决一个非常常见的问题。假设一个布局高度我并不知道,我希望一个子控件现在在右下角,这个时候使用RelativeLayout就有问题了,会把RelativeLayout的高度变成match_parent,而FrameLayout可以完美解决这个问题。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:foreground=""
    android:layout_height="wrap_content">
    <TextView
        android:background="@android:color/holo_blue_dark"
        android:layout_width="100dp"
        android:layout_height="100dp" />

    <TextView
        android:layout_gravity="right|bottom"
        android:text="显示在父类的右下角"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</FrameLayout>

AbsoluteLayout 绝对布局

    <declare-styleable name="AbsoluteLayout_Layout">
        <attr name="layout_x" format="dimension" />
        <attr name="layout_y" format="dimension" />
    </declare-styleable>
/**
 * @deprecated Use {@link android.widget.FrameLayout}, {@link android.widget.RelativeLayout}
 *             or a custom layout instead.
 */
@Deprecated
@RemoteView
public class AbsoluteLayout extends ViewGroup {
}

可以看到, AbsoluteLayout 没有自己的属性,而子控件也只有layout_xlayout_y,用于定位子控件的位置,AbsoluteLayout 几乎在实际的开发中是没人用的,而且已经被官方遗弃了,建议使用 RelativeLayout 和 FrameLayout 代替。

TableLayout 表格布局

    <declare-styleable name="TableLayout">
        <!-- The zero-based index of the columns to stretch. The column indices
             must be separated by a comma: 1, 2, 5. Illegal and duplicate
             indices are ignored. You can stretch all columns by using the
             value "*" instead. Note that a column can be marked stretchable
             and shrinkable at the same time. -->
        <attr name="stretchColumns" format="string" />
       <!-- The zero-based index of the columns to shrink. The column indices
             must be separated by a comma: 1, 2, 5. Illegal and duplicate
             indices are ignored. You can shrink all columns by using the
             value "*" instead. Note that a column can be marked stretchable
             and shrinkable at the same time. -->
        <attr name="shrinkColumns" format="string" />
        <!-- The zero-based index of the columns to collapse. The column indices
             must be separated by a comma: 1, 2, 5. Illegal and duplicate
             indices are ignored. -->
        <attr name="collapseColumns" format="string" />
    </declare-styleable>
  • stretchColumns:为设置运行被拉伸的列的序号,如android:stretchColumns="2,3"表示在第三列的和第四列的一起填补空白,如果要所有列一起填补空白,则用“*”符号,列号都是从0开始算的。
  • shrinkColumns:为设置被收缩的列的序号,收缩是用于在一行中列太多或者某列的内容文本过长,会导致某列的内容会被挤出屏幕,这个属性是可以帮助某列的内容进行收缩,用于防止被挤出的。
  • android:collapseColumns:为设置需要被隐藏的列的序号,使用该属性可以隐藏某列。

TableLayout 继承于 LinearLayout,可以由多个TableRow组成,显示多行。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="android:stretchColumns=0" />
    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:stretchColumns="0">
        <TableRow>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_red_dark"
                android:padding="20dp"
                android:text="ROW0" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_blue_dark"
                android:padding="20dp"
                android:text="ROW1" />
        </TableRow>
        <TableRow>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_red_dark"
                android:padding="20dp"
                android:text="ROW0" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_blue_dark"
                android:padding="20dp"
                android:text="ROW1" />
        </TableRow>
    </TableLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="android:shrinkColumns=0" />
    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:shrinkColumns="0">

        <TableRow>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_red_dark"
                android:padding="20dp"
                android:text="------------------------------------------------ROW0" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_blue_dark"
                android:padding="20dp"
                android:text="-------------------------------------------------ROW1" />
        </TableRow>
    </TableLayout>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="android:collapseColumns=0" />
    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:collapseColumns="1">
        <TableRow>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_red_dark"
                android:padding="20dp"
                android:text="ROW0" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_green_dark"
                android:padding="20dp"
                android:text="ROW1" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_blue_dark"
                android:padding="20dp"
                android:text="ROW2" />
        </TableRow>
    </TableLayout>
</LinearLayout>

GridLayout 网格布局

    <declare-styleable name="GridLayout">
        <!-- The orientation property is not used during layout. It is only used to
        allocate row and column parameters when they are not specified by its children's
        layout paramters. GridLayout works like LinearLayout in this case;
        putting all the components either in a single row or in a single column -
        depending on the value of this flag. In the horizontal case, a columnCount
        property may be additionally supplied to force new rows to be created when a
        row is full. The rowCount attribute may be used similarly in the vertical case.
        The default is horizontal. -->
        <attr name="orientation" />
        <!-- The maxmimum number of rows to create when automatically positioning children. -->
        <attr name="rowCount" format="integer" />
        <!-- The maxmimum number of columns to create when automatically positioning children. -->
        <attr name="columnCount" format="integer" />
        <!-- When set to true, tells GridLayout to use default margins when none are specified
        in a view's layout parameters.
        The default value is false.
        See {@link android.widget.GridLayout#setUseDefaultMargins(boolean)}.-->
        <attr name="useDefaultMargins" format="boolean" />
        <!-- When set to alignMargins, causes alignment to take place between the outer
        boundary of a view, as defined by its margins. When set to alignBounds,
        causes alignment to take place between the edges of the view.
        The default is alignMargins.
        See {@link android.widget.GridLayout#setAlignmentMode(int)}.-->
        <attr name="alignmentMode" />
        <!-- When set to true, forces row boundaries to appear in the same order
        as row indices.
        The default is true.
        See {@link android.widget.GridLayout#setRowOrderPreserved(boolean)}.-->
        <attr name="rowOrderPreserved" format="boolean" />
        <!-- When set to true, forces column boundaries to appear in the same order
        as column indices.
        The default is true.
        See {@link android.widget.GridLayout#setColumnOrderPreserved(boolean)}.-->
        <attr name="columnOrderPreserved" format="boolean" />
    </declare-styleable>
    <declare-styleable name="GridLayout_Layout">
        <!-- The row boundary delimiting the top of the group of cells
        occupied by this view. -->
        <attr name="layout_row" format="integer" />
        <!-- The row span: the difference between the top and bottom
        boundaries delimiting the group of cells occupied by this view.
        The default is one.
        See {@link android.widget.GridLayout.Spec}. -->
        <attr name="layout_rowSpan" format="integer" min="1" />
        <!-- The relative proportion of vertical space that should be allocated to this view
        during excess space distribution. -->
        <attr name="layout_rowWeight" format="float" />
        <!-- The column boundary delimiting the left of the group of cells
        occupied by this view. -->
        <attr name="layout_column" />
        <!-- The column span: the difference between the right and left
        boundaries delimiting the group of cells occupied by this view.
        The default is one.
        See {@link android.widget.GridLayout.Spec}. -->
        <attr name="layout_columnSpan" format="integer" min="1" />
        <!-- The relative proportion of horizontal space that should be allocated to this view
        during excess space distribution. -->
        <attr name="layout_columnWeight" format="float" />
        <!-- Gravity specifies how a component should be placed in its group of cells.
        The default is LEFT | BASELINE.
        See {@link android.widget.GridLayout.LayoutParams#setGravity(int)}. -->
        <attr name="layout_gravity" />
    </declare-styleable>
测试
<?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:columnCount="3">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button2" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

</GridLayout>

merge

merge 主要是进行UI布局的优化的,删除多余的层级,优化UI。

  • merge必须放在布局文件的根节点上。

  • merge并不是一个ViewGroup,也不是一个View,它相当于声明了一些视图,等待被添加。

  • merge标签被添加到A容器下,那么merge下的所有视图将被添加到A容器下。

  • 因为merge标签并不是View,所以在通过LayoutInflate.inflate方法渲染的时候, 第二个参数必须指定一个父容器,且第三个参数必须为true,也就是必须为merge下的视图指定一个父亲节点。

  • 因为merge不是View,所以对merge标签设置的所有属性都是无效的。

  • 使用parentTag指定被装在的parent的布局容器类型,例如 tools:parentTag="android.widget.FrameLayout",那么就可以预览到当前布局被装在进FrameLayout时候的效果。

<?xml version="1.0" encoding="utf-8"?>
<merge tools:parentTag="android.widget.LinearLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="TEXT" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="TEXT" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="TEXT" />
</merge>
image.png

相关文章

网友评论

    本文标题:FrameLayout、AbsoluteLayout、Table

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