全面总结之 布局 篇

来把常用组件总结一下,方便之后的自定义组件的文章。

先从布局开始。

LinearLayout - 线性布局

线性布局,该布局中的组件都是按照垂直或者水平排列。可以通过 android:orentation 这一属性来指定布局方向,该属性有 horizontal - 水平vertical - 垂直 两个值可选。

LinearLayout 还有一个重要的内容是这个布局形式可以使用权重的方式排列组件。使用 android:weight 属性为布局内的组件设置权重。默认是 0。

设置了权重的子组件会按照比例分配父空间中剩余的空间。

例如:

<?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="match_parent"
        android:layout_height="wrap_content"
        android:background="#000fff"
        android:text="111" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:background="#fff000"
        android:text="222" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="3"
        android:background="#a0a0a0"
        android:text="333" />
</LinearLayout>

显示如下:

来把常用组件总结一下,方便之后的自定义组件的文章。

先从布局开始。

LinearLayout

线性布局,该布局中的组件都是按照垂直或者水平排列。可以通过 android:orentation 这一属性来指定布局方向,该属性有 horizontal - 水平vertical - 垂直 两个值可选。

LinearLayout 还有一个重要的内容是这个布局形式可以使用权重的方式排列组件。使用 android:weight 属性为布局内的组件设置权重。默认是 0。

设置了权重的子组件会按照比例分配父空间中剩余的空间。

例如:

<?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="match_parent"
        android:layout_height="wrap_content"
        android:background="#000fff"
        android:text="111" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:background="#fff000"
        android:text="222" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="3"
        android:background="#a0a0a0"
        android:text="333" />
</LinearLayout>

显示如下:

可以看到,没有设置权限的 111 只是占据文字本身的高度,而 222 的权重是 2,所以它占了剩余部分的 2/5,而 333 权重是 3,所以占了 3/5。

LinearLayout 还有哪些属性可以使用呢?看一下它的官方文档:LinearLayout.LayoutParams

  • android:gravity:这个属性用来控制其子 View 在其内部的位置,如文本控件在布局中的位置,按钮中的文字在按钮上的位置等等。有如下几个值可选:

  • android:layout_gravity:这个属性是用来控制该组件在父布局中的位置有,属性值和 android:gravity 相同。

一个例子来展示二者的区别:

<?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:gravity="center"
    android:orientation="vertical"
    android:layout_margin="20dp">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是一个文本" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:gravity="left"
        android:text="start" />
</LinearLayout>

该布局文件效果如下:

文本控件和按钮都在屏幕中间,是因为在 LinearLayout 当中设置了 android:gravity="center"

按钮在中间的右边,是因为按钮控件设置了 android:layout_gravity="right",而按钮上的文字是位于按钮的左边,是因为设置了 android:gravity="left"

  • android:margin:该属性通俗的讲就是组件外边距,用来设置围绕在元素周围的“空白”处。
    该属性有几个特定的分支:

有两个属性可能会有一些懵逼,layout_marginStartlayout_marginEnd,这两个属性是用来适配哪些从右往左写的语言的(例如阿拉伯语),当系统设置为阿拉伯语时,layout_marginStart 就相当于 layout_marginRight,这是系统自动实现的。

  • android:padding:该属性通俗的讲就是设置元素的内边距。其也有几个特定分支,和 adnroid:margin 一样。

一个例子演示一下 margin 和 padding 的区别:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="50dp"
    android:background="#B3EE3A"
    android:orientation="vertical"
    android:padding="30dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00C5CD"
        android:text="This is a string" />
</LinearLayout>

该布局显示如下:

  • android:divider 和 android:showDividers:这个两个属性搭配使用,用来给布局中添加分割线。其中 android:divider 用来指定分割线的样式,可以是一张图片,也可以是 xml 绘制的 shape。android:showDividers 用来指定分割线的位置,有 beginning|middle|end|none 几个值可选。

例子:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:divider="@drawable/cutting"
    android:gravity="center"
    android:showDividers="beginning|middle|end">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00C5CD"
        android:text="This is a string" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00C5CD"
        android:text="This is a string" />
</LinearLayout>

```xml




该布局显示为:
![](https://www.li-xyz.com:1443/content/images/2017/06/2865879473.png)

 - android:baselineAligned:该属性是用来设置布局控件中子控件内的文字的基线是否对齐。有 true 和 false 两个值可选,默认为 true。

例子:
```xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="true|false"
    android:orientation="horizontal">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00C5CD"
        android:text="one"
        android:textSize="36dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00C5CD"
        android:text="two"
        android:textSize="16dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="50dp"
        android:text="three"/>

</LinearLayout>

显示如下:

更多关于 LinearLayout 的内容,请查看: LinearLayoutLinearLayout.LayoutParams.html


RelativeLayout - 相对布局

和线性布局不同,相对布局是使用“相对位置”来布局子控件的布局。每个子控件的位置可以相对于相邻组件来设置(例如在 xxx 组件的左边、右边),或者相对于父控件区域位置来指定(例如位于布局的底部等)。

常用属性:

  • 以父布局为基准
    • android:layout_alignParentLeft:和父布局左对齐
    • android:layout_alignParentRight:和父布局右对齐
    • android:layout_alignParentTop:和父布局上部对齐
    • android:layout_alignParentBottom:和父布局底部对齐
    • android:layout_alignParentStart:和 marginStart 一样,是为了适配从左往右书写的语言
    • android:layout_alignParentEnd:和 marginEnd 一样,是为了适配从左往右书写的语言
    • android:layout_centerInParent:在父布局中央显示

该系列的值为 true 或者 false。

示例:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="30dp">
    <Button
        android:id="@+id/bt0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="0" />

    <Button
        android:id="@+id/bt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:text="1" />

    <Button
        android:id="@+id/bt2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="2" />

    <Button
        android:id="@+id/bt3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:text="3" />

    <Button
        android:id="@+id/bt4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:text="4" />
</RelativeLayout>

其效果如下:

  • 以其他子控件为基准
    • android:layout_above:该控件位于标准控件的上方
    • android:layout_below:该控件位于标准控件的下方
    • android:layout_toRightOf:该控件位于标准控件的右�方
    • android:layout_toLeftOf:该控件位于标准控件的左方
    • android:layout_toStartOf
    • android:layout_toEndOf

这些属性需要使用“@id/xxxx”来引入标准控件的id,并且当一个控件以另外一个控件为标准时,另一个控件一定要定义在这个控件前面,否则会出现找不到id的情况。

实例:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Button 3" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/button3"
        android:layout_toLeftOf="@id/button3"
        android:text="Button 1" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/button3"
        android:layout_toRightOf="@id/button3"
        android:text="Button 2" />

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/button3"
        android:layout_toLeftOf="@id/button3"
        android:text="Button 4" />

    <Button
        android:id="@+id/button5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/button3"
        android:layout_toRightOf="@id/button3"
        android:text="Button 5" />
</RelativeLayout>

该布局显示如下:

  • 和标准组件边缘对齐的属性
    • android:layout_alignRight:表示该控件的右边缘和标准控件的右边缘对齐
    • android:layout_ alignLeft:表示该控件的左边缘和标准控件的左边缘对齐
    • android:layout_alignTop:表示该控件的上边缘和标准控件的上边缘对齐
    • android:layout_alignBottom:表示该控件的下边缘和标准控件的下边缘对齐

FrameLayout - 帧布局

框架布局没有任何定位方式,帧布局容器每加入一个组件创建一个空白区域,每个组件占据一帧,添加的组件是一个一个叠在一起的,默认位置是左上角。

示例:


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/firstView"
        android:text="第一层"
        android:textSize="50sp"
        android:textColor="#000000"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/secondView"
        android:text="第二层"
        android:textSize="30sp"
        android:textColor="#ffff00"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/thirdView"
        android:text="第三层"
        android:textSize="15sp"
        android:textColor="#ff00ff"/>

</FrameLayout>

该布局显示如下:

难道真的是FrameLayout中的子元素完全无法控制自身在布局中的位置吗?其实不是的,android:laytou_gravity属性可以改编控件在布局中的位置

如下:


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/firstView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="第一层"
        android:textColor="#000000"
        android:textSize="50sp" />

    <TextView
        android:id="@+id/secondView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="第二层"
        android:textColor="#ffff00"
        android:textSize="30sp" />

    <TextView
        android:id="@+id/thirdView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:text="第三层"
        android:textColor="#ff00ff"
        android:textSize="15sp" />

</FrameLayout>

该布局显示如下:

该布局还有两个个重要属性:

  • android:foreground:设置改帧布局容器的前景图像
  • android:foregroundGravity:设置前景图像显示的位置

示例:


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:foreground="@mipmap/ic_launcher"
    android:foregroundGravity="bottom|left">


    <TextView
        android:id="@+id/firstView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="第一层"
        android:textColor="#000000"
        android:textSize="50sp" />

    <TextView
        android:id="@+id/secondView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="第二层"
        android:textColor="#ffff00"
        android:textSize="30sp" />

    <TextView
        android:id="@+id/thirdView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:text="第三层"
        android:textColor="#ff00ff"
        android:textSize="15sp" />

</FrameLayout>

该布局显示如下:


TableLayout - 表格布局

TableLayout 运行我们使用表格的方式来排列控件,它的本质依然是线性布局。表格布局采用行、列的形式来管理控件,TableLayout 并不需要明确的声明包含多少行多少列,而是通过添加 TableRow、其他组件来控制表格的行数和列数。

每次向 Table 中添加一个 TableRow,该 TableRow 就是一个表格行,TableRow 也是容器,因此它也可以不断的添加其他组件,每添加一个子组件该表格就增加一列。

例如:


<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="30dp"
    android:stretchColumns="1">

    <TableRow>

        <TextView
            android:layout_height="wrap_content"
            android:text="账户:" />

        <EditText
            android:id="@+id/usernameInput"
            android:layout_height="wrap_content"
            android:hint="输入要注册的用户名" />
    </TableRow>

    <TableRow>

        <TextView
            android:layout_height="wrap_content"
            android:text="密码:" />

        <EditText
            android:id="@+id/passwordInput"
            android:layout_height="wrap_content"
            android:hint="输入要密码"
            android:inputType="textPassword" />
    </TableRow>

    <TableRow>

        <Button
            android:id="@+id/loginButton"
            android:layout_height="wrap_content"
            android:layout_span="2"
            android:text="登录" />
    </TableRow>
</TableLayout>

该布局演示如下:

该布局有以下几个重要属性:

  • android:collapseColumns="0":隐藏第0列
  • android:shrinkColumns="0":收缩第0列
  • android:stretchColumns="0":拉伸第0列

GridLayout - 网格布局

网格布局是 Android4.0 新增的布局管理器,因此需要在 Android4.0 之后的版本才可以使用,之前的平台使用该布局的话,需要导入相应的支持库。

GridLayout 的作用类似于 HTML 中的 table 标签,它把整个容器划分成 row*column 个网格,每个网格都可以放置一个组件,也可以设置一个组件横跨多少列、多少行。

GridLayout 提供了 setRowCount(int) 和 setColumnCount(int) 方法来控制该网格的行数和列数。


<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:rowCount="6" android:columnCount="4" android:id="@+id/root"> <!-- 定一个一个横跨四列的文本框,并设置该文本框的前景色、背景色等属性 --> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_columnSpan="4" android:textSize="50sp" android:layout_marginLeft="4px" android:layout_marginRight="4px" android:padding="5px" android:layout_gravity="right" android:background="#eee" android:textColor="#000" android:text="0" /> <!-- 定义一个横跨四列的按钮 --> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_columnSpan="4" android:text="清除"/> <!-- 添加其他按钮 --> <Button android:text="7" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="8" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="9" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="/" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="4" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="5" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="6" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="*" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="1" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="2" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="3" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="-" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="0" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="." android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="+" android:layout_rowWeight="1" android:layout_columnWeight="1"/> <Button android:text="=" android:layout_rowWeight="1" android:layout_columnWeight="1"/> </GridLayout>

该布局显示如下:

该布局有以下几个属性:

  • 设置有多少行:android:rowCount="4"
  • 设置有多少列:android:columnCount="4"
  • 组件在第几行:android:layout_row = "1"
  • 组件在第几列:android:layout_column = "2"
  • 横跨几行:android:layout_rowSpan = "2"
  • 横跨几列:android:layout_columnSpan = "3"

ConstraintLayout - 依赖布局

依赖布局是 Google I/O 2016 上发布的,大概看了一下,感觉这个布局的出现,更适合把界面设计工作交给设计师来操作,设计师不需要懂代码,直接拖曳控件就好,对于程序员来说,似乎并不是很实用,因为代码量似乎变得多了。。。

有人总结了很好的文章,可以看这里:


百分比布局库

这个严格意义上讲并不是一个布局,它提供了两个“布局”,在这两个布局中,我们可以使用百分比来确定组件的大小位置,是不是很棒?

使用该库,需要引入依赖:compile 'com.android.support:percent:22.2.0'

该库提供了两个类:PercentFrameLayout 和 PercentRelativeLayout,顾名思义,就是 FrameLayout 和 RelativeLayout 的延伸了。

PercentFrameLayout 支持以下属性:

  • layout_widthPercent:用百分比的形式设置组件宽度

  • layout_heightPercent:用百分比的形式设置组件高度

  • layout_marginPercent:用百分比的形式设置 margin

  • layout_marginLeftPercent:用百分比的形式设置 marginLeft

  • layout_marginTopPercent:用百分比的形式设置 marginTop

  • layout_marginRightPercent:用百分比的形式设置 marginRight

  • layout_marginBottomPercent:用百分比的形式设置 marginBottom

  • layout_marginStartPercent:用百分比的形式设置 marginStart

  • layout_marginEndPercent:用百分比的形式设置 marginEnd

  • layout_aspectRatio:通过只设置width或者height和layout_aspectRatio这种比例值的方式来让第另一个值自动计算。

例子:


<android.support.percent.PercentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:background="#fff000"
        android:text="1"
        app:layout_heightPercent="20%"
        app:layout_marginLeftPercent="50%"
        app:layout_widthPercent="10%" />

    <Button
        android:layout_width="100dp"
        android:background="#00BFFF"
        android:text="2"
        app:layout_aspectRatio="200%" />

    <Button
        android:layout_width="100dp"
        android:background="#40E0D0"
        android:text="3"
        app:layout_aspectRatio="100%"
        app:layout_marginTopPercent="50%" />

</android.support.percent.PercentFrameLayout>

该布局显示如下:

PercentRelativeLayout 可以使用的属性也和 PercentFrameLayout 一样,例子就不举了。

更多参考:


布局优化

有时候我们的布局会非常复杂,如果还是直接简单粗暴的堆积组件,那么系统在绘制布局的时候会相对的耗时耗力,这个时候布局优化就显得特别重要了。布局优化主要有以下几点:

  • 善用 RelativeLayout:在RelativeLayout和LinearLayout同时能够满足需求时,尽量使用RelativeLayout,这一点可以从我们MainActivity默认布局就可以看出,默认是RelativeLayout,因为可以通过扁平的RelativeLayout降低LinearLayout嵌套所产生布局树的层级。
    Android提供了几种方便的布局管理器,大多数时候,你只需要这些布局的一部分基本特性去实现UI。 一般情况下用LinearLayout的时候总会比RelativeLayout多一个View的层级。而每次往应用里面增加一个View,或者增加一个布局管理器的时候,都会增加运行时对系统的消耗,因此这样就会导致界面初始化、布局、绘制的过程变慢。

举个例子来看一下:

我们要实现以下布局:

使用 LinearLayout


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp">


    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="使用 LinearLayout" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="使用 LinearLayout" />
    </LinearLayout>
</LinearLayout>

可以看到,使用 LinearLayout 来实现这个布局,会有两层:

使用 RelativeLayout


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp">


    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:layout_toRightOf="@id/image"
        android:text="使用 RelativeLayout" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/text"
        android:layout_marginTop="5dp"
        android:layout_toRightOf="@id/image"
        android:text="使用 RelativeLayout" />

</RelativeLayout>

使用 RelativeLayout 来实现,就会只有一层:

层级减少了,渲染的时间自然也就减少了。

  • 使用 <include> 标签
    有很多时候我们的很多页面都会使用同一个组件,例如进度条等等。这个时候就可以把这些公用的部分单独拿出来,在需要使用这些的地方,就可以使用 <include> 标签来引入这个公共的组件。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:layout_toRightOf="@id/image"
        android:text="AppName" />
</RelativeLayout>

然后在我们的布局中引入这个布局


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp">


    <include
        android:id="@+id/title"
        layout="@layout/title_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:text="111111111111111111111111111111" />

</RelativeLayout>

最后显示如下:

  • 使用 <merge> 标签
    <merge> 标签在你嵌套 Layout 时取消了 UI 层级中冗余的 ViewGroup。比如,如果你有一个 Layout 是一个竖直方向的 LinearLayout,其中包含两个连续的 View 可以在别的 Layout 中重用,那么你会做一个 LinearLayout 来包含这两个 View,以便重用。不过,当使用一个 LinearLayout 作为另一个 LinearLayout 的根节点时,这种嵌套 LinearLayout 的方式除了减慢你的 UI 性能外没有任何意义。
    为了避免这种情况,你可以用 <merge> 元素来替代可重用 Layout 的根节点。例如:
<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/add"/>

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/delete"/>

</merge>

现在,当你要将这个 Layout 包含到另一个 Layout 中时(并且使用了 <include> 标签),系统会忽略 <merge> 标签,直接把两个 Button 放到 Layout 中 <include> 的所在位置。

Copyright© 2020-2022 li-xyz 冀ICP备2022001112号-1