最近的情绪,最近的状态,仿佛没法说个一二三四五。
做 Android 好几年了,从单纯的 Android,到当初大杂烩,这个滋味儿,真的是百感交汇。
文章的内容类型素来都是 Notes,这次对老本行进行回顾下。
致力呀,万一一不小心优良了呢?万一一不小心和鸡老大肩并肩了呢~
回顾 Android 布局
已经无论面试也好,闲聊也罢,谈起 Android 布局,总是不假思索间接说出五大布局。而到当初 2020 年末了,仍然还是已经的五大布局吗?
这里简略的整顿了一部分,依照集体应用频率排序:
- ConstraintLayout: 束缚布局
- LinearLayout: 线性布局
- RelativeLayout: 绝对定位布局
- FrameLayout: 帧布局
- GridLayout: 网格布局
- TableLayout: 表格布局
- AbsoluteLayout(已弃用): 相对定位布局
- BlinkLayout(公有类): 布灵布灵闪动布局
这里说下我是怎么找的这些布局,不便和我一样小白触类旁通。
援用 Flutter 一句话,万物皆为 Weight。而在 Android 中,直观而言,能看到的都是 View,而 View 也分不同的作用,例如 TextView、ImageView 等根底罕用 View,仅仅为了展现或者间接响应用户操作。而基于 View 衍生出的 ViewGroup 则是通过包裹各种 View,最终出现特有的成果。例如 LinearLayout 在原有 ViewGroup 根底上新增程度 / 垂直排列形式、RelativeLayout 在原根底上新增基于某个控件进行排列等。所以说间接在 Android API reference 搜寻 ViewGroup,查看间接子类以及间接子类即可,如下所示:
文末已附上对应的链接,欢送各位大佬指导~
五个星星我认为是必须要把握的,比拟实战中呈现评率很高了。一星简略理解,面试和面试官吹个水就好~
反正晓得必定要比什么都不晓得要强很多的~
文中借用图片,文末均以附上地址链接~
一、ConstraintLayout ⭐️⭐️⭐️⭐️⭐️
- ConstraintLayout 通过各种束缚进行排列子 View 的布局。
这个货色最牛掰的一点就是,反对可视化工具操作,及其不便。在上面的事例中也会多多少少体验一波~
应用形式:
- 增加 Maven 库
repositories {google()
}
- 增加 ConstraintLayout 依赖
dependencies {implementation "androidx.constraintlayout:constraintlayout:2.0.4"}
当然如果你的 Android Studio 降级到最新版本,默认布局便是 ConstraintLayout,还是要去 build 中查看下版本。我也遗记是哪儿个版本设置默认根布局了。
当然,贴心的 Android Studio 也提供一键转化根布局性能,如下图:
1. 绝对定位 layout_constraintXXX
绝对定位是在 ConstraintLayout 中创立布局根本构建块之一。这些束缚容许一个 View 基于某个 View 进行定位,同样咱们能够在程度方向以及垂直方向进行束缚 View:
- 程度轴: 左,右,终点和起点
- 垂直轴: 顶部,底部和文本基线
如下,实现将 B 按钮定位在 A 按钮右侧:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/buttonA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A" />
<Button
android:id="@+id/buttonB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
app:layout_constraintStart_toEndOf="@+id/buttonA" />
</androidx.constraintlayout.widget.ConstraintLayout>
上面借用官网图,为了更好的了解上面的属性:
属性 | 作用 |
---|---|
layout_constraintLeft_toLeftOf | 以后 View 左侧对标指标 View 左侧 |
layout_constraintLeft_toRightOf | 以后 View 左侧对标指标 View 右侧 |
layout_constraintRight_toLeftOf | 以后 View 右侧对标指标 View 左侧 |
layout_constraintRight_toRightOf | 以后 View 右侧对标指标 View 右侧 |
layout_constraintTop_toTopOf | 以后 View 顶部对标指标 View 顶部 |
layout_constraintTop_toBottomOf | 以后 View 顶部对标指标 View 底部 |
layout_constraintBottom_toTopOf | 以后 View 底部对标指标 View 顶部 |
layout_constraintBottom_toBottomOf | 以后 View 底部对标指标 View 底部 |
layout_constraintBaseline_toBaselineOf | 以后 View 与指标 View 文字基线对齐 |
layout_constraintStart_toEndOf | 以后 View 终点对标指标 View 起点 |
layout_constraintStart_toStartOf | 以后 View 终点对标指标 View 终点 |
layout_constraintEnd_toStartOf | 以后 View 起点对标指标 View 终点 |
layout_constraintEnd_toEndOf | 以后 View 起点对标指标 View 起点 |
2. 边距 Margins
属性 | 作用 |
---|---|
android:layout_marginStart | 以后 View 间隔指标 View 左侧间距 |
android:layout_marginEnd | 以后 View 间隔指标 View 右侧间距 |
android:layout_marginLeft | 以后 View 间隔指标 View 左侧间距 |
android:layout_marginTop | 以后 View 间隔指标 View 顶部间距 |
android:layout_marginRight | 以后 View 间隔指标 View 右侧间距 |
android:layout_marginBottom | 以后 View 间隔指标 View 底部间距 |
3. 指标 View 暗藏时,以后 View 边距 Margins
当指标 View 的可见性为 View.GONE 时,还能够应用以下属性设置以后 View 在前者 GONE 状况下的 margin。
属性 | 作用 |
---|---|
layout_goneMarginStart | 指标 View 暗藏时,以后 View 间隔左侧间距 |
layout_goneMarginEnd | 指标 View 暗藏时,以后 View 间隔右侧间距 |
layout_goneMarginLeft | 指标 View 暗藏时,以后 View 间隔左侧间距 |
layout_goneMarginTop | 指标 View 暗藏时,以后 View 间隔顶部间距 |
layout_goneMarginRight | 指标 View 暗藏时,以后 View 间隔右侧间距 |
layout_goneMarginBottom | 指标 View 暗藏时,以后 View 间隔底部间距 |
如下成果:
默认 A、B 按钮 Margin 为 50dp,在 A 按钮暗藏状态下,B 按钮间隔 A 的边距变为 30dp:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="50dp"
android:text="A"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="50dp"
android:text="B"
app:layout_constraintStart_toEndOf="@+id/button"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginStart="30dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
4. 居中定位和偏差比例
很多时候,咱们须要的成果为居中,同时某些状况下也须要去设置比例,比方宽度百分比,上面间接上效果图:
代码如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:layout_width="180dp"
android:layout_height="180dp"
android:scaleType="fitXY"
android:src="@drawable/img"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.19"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.16000003" />
</androidx.constraintlayout.widget.ConstraintLayout>
这里再次回顾下以后例子中要害内容:
属性 | 作用 |
---|---|
layout_constraintStart_toStartOf | 当取值为 parent 代表与父容器对齐 |
layout_constraintEnd_toEndOf | |
layout_constraintTop_toTopOf | |
layout_constraintBottom_toBottomOf |
上面是各个组合形式对应的成果:
- start 和 end 组合,便是程度居中
- top 和 bottom 组合,便是垂直居中
- start、end、top、bottom 组合便是程度 / 垂直居中
属性 | 作用 |
---|---|
layout_constraintVertical_bias | 垂直形式占比 |
layout_constraintHorizontal_bias | 程度形式占比 |
5. 圆形定位
这里为了不便,我就间接截图了:
上面着手实现如下成果:
代码如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/buttonA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是核心"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/buttonB"
app:layout_constraintCircle="@id/buttonA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintCircleAngle="45"
app:layout_constraintCircleRadius="100dp"
android:text="我是花儿" />
</androidx.constraintlayout.widget.ConstraintLayout>
属性 | 作用 |
---|---|
layout_constraintCircle | 指定圆心 View ID |
layout_constraintCircleAngle | 设置以后 View 角度 |
layout_constraintCircleRadius | 设置半径 |
6. 尺寸限度
也能够为 ConstraintLayout 本身定义最小和最大大小:
属性 | 作用 |
---|---|
android:minWidth | 设置布局的最小宽度 |
android:minHeight | 设置布局的最小高度 |
android:maxWidth | 设置布局的最大宽度 |
android:maxHeight | 设置布局的最大高度 |
当 ConstraintLayout 外部子 View 宽度 / 高度为 0dp,则同等于 match_parent。
7. 尺寸百分比
这个其实我蛮喜爱的,相似百分比布局,爽的很。
应用这块须要留神:
- 设置宽度 / 高度百分比时,须要先将对应的宽 / 高设置为 0dp;
- 默认值应设置为百分比 app:layout_constraintWidth_default=”percent” 或 app:layout_constraintHeight_default=”percent”;(这点感觉没啥用,不信你看上面)
- layout_constraintWidth_percent 或者 layout_constraintHeight_percent 属性设置为介于 0 和 1 之间的值;
上面着手实现如下成果:
第一个 View 宽高占比为:0.3:0.2,第二个 View 宽度占比为 1:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/buttonA"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="我是核心"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.2"
app:layout_constraintWidth_percent="0.3"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/buttonB"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="我是花儿"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.32"
app:layout_constraintWidth_percent="1" />
</androidx.constraintlayout.widget.ConstraintLayout>
属性 | 作用 |
---|---|
layout_constraintHeight_percent | 高度占比 |
layout_constraintWidth_percent | 宽度占比 |
作为一枚不折不扣的程序员而言,能省事儿相对省事儿,下面宽高还得写两次,能不能一次搞定呢?
上面实现一个宽高比为 16:9:
<Button
android:id="@+id/buttonA"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="我是核心"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
成果如下:
8. 链式
这个成果也是蛮不错的,有些相似前端的 Flex,感觉还是不错的。
设置属性 layout_constraintHorizontal_chainStyle 或 layout_constraintVertical_chainStyle 在链的第一个元素上时,链的行为将依据指定的款式而扭转(默认为 CHAIN_SPREAD)。
演示图如下:
代码如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="130dp">
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
app:layout_constraintEnd_toStartOf="@+id/button3"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button1" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="C"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button2" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
app:layout_constraintEnd_toStartOf="@+id/button2"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
9. 辅助对象 Guideline
据官网所言,此为 ConstraintLayout 辅助工具,默认为 View.GONE。
应用形式次要分为两种状况:
- 百分比定位: layout_constraintGuide_percent
- 相对定位: layout_constraintGuide_begin / layout_constraintGuide_end
最初咱们能够通过 orientation 去设置以后辅助线的显示方式,程度 / 垂直。
我集体蛮喜爱百分比形式,先来个成果:
如何确保图片在每种机型上都位于屏幕百分之 15 高度的地位呢?通过辅助线百分比分分钟的事儿。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:src="@drawable/img"
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline4" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.15" />
</androidx.constraintlayout.widget.ConstraintLayout>
而对于相对定位更好了解啦。这里间接录制效果图咯,大家留神察看点击 Icon 后代码以及成果变动:
番外:理解束缚布局性能劣势
文末已附上链接地址,这里只对集体感兴趣的局部做出节选。
借助 Google 翻译学习,配合本人了解,如谬误,欢送斧正~
针对传统布局以及束缚布局的劣势,这里以上面成果为例,简略进行比照:
传统布局绘制层级:
<RelativeLayout>
<ImageView />
<ImageView />
<RelativeLayout>
<TextView />
<LinearLayout>
<TextView />
<RelativeLayout>
<EditText />
</RelativeLayout>
</LinearLayout>
<LinearLayout>
<TextView />
<RelativeLayout>
<EditText />
</RelativeLayout>
</LinearLayout>
<TextView />
</RelativeLayout>
<LinearLayout >
<Button />
<Button />
</LinearLayout>
</RelativeLayout>
束缚布局绘制层级:
<android.support.constraint.ConstraintLayout>
<ImageView />
<ImageView />
<TextView />
<EditText />
<TextView />
<TextView />
<EditText />
<Button />
<Button />
<TextView />
</android.support.constraint.ConstraintLayout>
直观上从两种计划绘制层级相比,显著束缚布局劣势更大。至多相比传统 RelativeLayout 少绘制几个 ViewGroup。
这里从官网博文中能够得悉 Android 绘制视图过程包含如下三个阶段:
-
测量(Measure)
- 零碎从视图树自顶向下遍历,以确定每个 ViewGroup 和 View 元素大小。而测量 ViewGroup 时,还将测量其子集 View。
-
布局(Layout)
- 从上到下的遍历,通过在测量阶段确定的大小来确定子 View 的地位。
-
绘制(Draw)
- 零碎执行的一个自上而下的遍历,对于视图树中的每个对象,都会创立一个 Canvas 对象,已将绘图命令发送 GPU。这些命令包含 ViewGroup 和 View 大小、地位,这是零碎在前两个阶段中确定的内容。
所以,咱们能够得出一个概念,绘制层级越深,耗费越大。反之,耗费则低,性能越高。
测量后果:ConstraintLayout 更快。
ConstraintLayout 在测量 / 布局阶段的性能比 RelativeLayout 好约 40%:
二、LinearLayout ⭐️⭐️⭐️⭐️
- LinearLayout 是行内以程度形式 / 垂直形式排列的布局容器。
罕用属性一览:
属性 | 作用 |
---|---|
android:orientation | 行内排列形式(horizontal/vertical),默认程度排列 |
android:gravity | 行内 View 对齐形式 |
android:weightSum | 行内可设置的最大占比权重 |
android:layout_weight | 以后 View 占比权重 |
android:baselineAligned | 父容器布局是否对齐子 View 基线 |
android:baselineAlignedChildIndex | 指定基线对齐的子 View |
来个简略的成果:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:measureWithLargestChild="true"
android:padding="15dp"
android:weightSum="1"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="勾销" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="确定" />
</LinearLayout>
三、RelativeLayout ⭐️⭐️⭐️⭐️
- RelativeLayout 是一个以绝对地位显示子视图的视图组。
罕用属性:
属性 | 作用 |
---|---|
android:layout_alignParentTop | 以后 View 上边缘和父容器上边缘对齐 |
android:layout_alignParentEnd | 以后 View 上边缘和父容器右边缘对齐 |
android:layout_alignParentBottom | 以后 View 上边缘和父容器下边缘对齐 |
android:layout_alignParentStart | 以后 View 上边缘和父容器左边缘对齐 |
android:layout_centerHorizontal | 以后 View 基于父容器程度居中 |
android:layout_centerVertical | 以后 View 基于父容器垂直居中 |
android:layout_centerInParent | 以后 View 基于父容器程度居中并垂直居中 |
android:layout_alignTop | 以后 View 位于指标 View 顶部 |
android:layout_toEndOf | 以后 View 位于指标 View 右侧 |
android:layout_below | 以后 View 位于指标 View 底部 |
android:layout_toStartOf | 以后 View 位于指标 View 左侧 |
着手实现如下成果:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="130dp"
android:padding="15dp">
<ImageView
android:id="@+id/ivAvatar"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:scaleType="fitXY"
android:src="@drawable/img" />
<TextView
android:id="@+id/tvNickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_toEndOf="@id/ivAvatar"
android:text="昵称:HLQ_Struggle" />
<TextView
android:id="@+id/tvLevel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tvNickname"
android:layout_marginStart="12dp"
android:layout_marginTop="15dp"
android:layout_toEndOf="@id/ivAvatar"
android:text="等级:V1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tvLevel"
android:layout_alignParentBottom="true"
android:layout_marginStart="12dp"
android:layout_marginTop="15dp"
android:layout_toEndOf="@id/ivAvatar"
android:text="性别:男" />
</RelativeLayout>
四、FrameLayout ⭐️⭐️⭐️⭐️
- FrameLayout 默认将控件层叠搁置屏幕左上角。子 View 通过 android:layout_gravity 去设置本身显示地位。
比拟重要的几个属性:
- android:layout_gravity: 子 View 对齐形式
- android:foreground: 前景图
- android:foregroundGravity: 前景图地位
上面开始实现如下成果:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="@android:drawable/btn_star"
android:foregroundGravity="right|bottom"
android:padding="30dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="< 首页" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="更多" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="首页" />
</FrameLayout>
五、GridLayout ⭐️
- GridLayout 是以网格模式显示子级 View 元素的 ViewGroup。
先来看看要害属性:
- android:columnCount: 列数
- android:rowCount: 行数
GridLayout 子 View 属性:
- android:layout_column: 以后 View 从第几列开始显示
- android:layout_columnSpan: 以后 View 占据列数
- android:layout_row: 以后 View 从第几行开始显示
- android:layout_rowSpan: 以后 View 所占行数
- android:layout_gravity: 对齐形式
比拟典型的例子就是计算器了吧:
代码如下:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnCount="4"
android:rowCount="6">
<TextView
android:layout_columnSpan="4"
android:layout_gravity="fill"
android:layout_margin="6dp"
android:background="#f5f5f5"
android:text="0"
android:textSize="50sp" />
<Button
android:layout_columnSpan="2"
android:layout_gravity="fill"
android:text="回退" />
<Button
android:layout_columnSpan="2"
android:layout_gravity="fill"
android:text="清空" />
<Button android:text="+" />
<Button android:text="1" />
<Button android:text="2" />
<Button android:text="3" />
<Button android:text="-" />
<Button android:text="4" />
<Button android:text="5" />
<Button android:text="6" />
<Button android:text="*" />
<Button android:text="7" />
<Button android:text="8" />
<Button android:text="9" />
<Button android:text="/" />
<Button
android:layout_width="wrap_content"
android:text="." />
<Button android:text="0" />
<Button android:text="=" />
</GridLayout>
六、TableLayout ⭐️
- TableLayout 是以行和列显示子级 View 元素的 ViewGroup。
来个成果理论阐明:
TableLayout 行内 View 默认占据一行的宽度。如果想一行蕴含多列,则须要用 TableRow 包裹,如下局部代码:
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:text="9*9=81" />
<TableRow>
<TextView
android:text="9*8=72" />
<TextView
android:text="8*8=64" />
</TableRow>
<TableRow>
<TextView
android:text="9*8=72" />
<TextView
android:text="8*8=64" />
<TextView
android:text="8*8=64" />
</TableRow>
</TableLayout>
- android:stretchColumns: 设置某列宽度为残余行宽度
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="0"> <!-- 第一列宽度为残余行宽度 -->
<TableRow>
<Button
android:text="我是第一列" />
<Button
android:text="我是第二列" />
</TableRow>
</TableLayout>
- android:collapseColumns: 暗藏某列
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:collapseColumns="0,2">
<TableRow>
<Button
android:text="我是第一列" />
<Button
android:text="我是第二列" />
<Button
android:text="我是第三列" />
<Button
android:text="我是第四列" />
</TableRow>
</TableLayout>
- android:shrinkColumns: 膨胀某列
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="0">
<!-- ... -->
</TableLayout>
谷歌这里提供了一个不错的成果,感兴趣的能够本人尝试一下,如下:
七、AbsoluteLayout ⭐️
应用形式:
- 依据子级的 x/y 坐标确定本身地位。灵活性较差,后续不易保护。
且在 Api 30 中已弃用。
上面实现如下成果:
第二个 TextView 位于第一个 TextView x/y 轴间隔别离为 100dp:
<AbsoluteLayout
android:layout_width="0dp"
android:layout_height="300dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="世界是美妙的~" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="100dp"
android:layout_y="100dp"
android:text="你在哪儿~" />
</AbsoluteLayout>
八、BlinkLayout ⭐️
这个货色就比拟神奇了,一闪一闪,布灵布灵。先来个成果:
作用就是每隔 500ms 执行一次绘制,出现的成果就是布灵布灵一闪一闪的。
应用形式也是比拟 easy:
<blink
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="世界是美妙的~" />
</blink>
源码绝对比拟少,上面贴一下,不便当前想看随时看????:
private static class BlinkLayout extends FrameLayout {
private static final int MESSAGE_BLINK = 0x42;
private static final int BLINK_DELAY = 500;
private boolean mBlink;
private boolean mBlinkState;
private final Handler mHandler;
public BlinkLayout(Context context, AttributeSet attrs) {super(context, attrs);
mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {if (msg.what == MESSAGE_BLINK) {if (mBlink) {
mBlinkState = !mBlinkState;
makeBlink();}
invalidate();
return true;
}
return false;
}
});
}
private void makeBlink() {Message message = mHandler.obtainMessage(MESSAGE_BLINK);
mHandler.sendMessageDelayed(message, BLINK_DELAY);
}
/**
* View 附加到 window 上的时候进行回调 适宜初始化一些操作
*/
@Override
protected void onAttachedToWindow() {super.onAttachedToWindow();
mBlink = true;
mBlinkState = true;
makeBlink();}
/**
* View 拆散 window 的时候进行回调 适宜销毁,重置一些操作
*/
@Override
protected void onDetachedFromWindow() {super.onDetachedFromWindow();
mBlink = false;
mBlinkState = true;
mHandler.removeMessages(MESSAGE_BLINK);
}
/**
* 散发子组件进行绘制
* @param canvas
*/
@Override
protected void dispatchDraw(Canvas canvas) {if (mBlinkState) {super.dispatchDraw(canvas);
}
}
}
The end
永远不要进行摸索。
很多时候,十分钟的摸索会给你带来不一样的世界。
一起致力,一起期待,一起致力为了将来变得优良吧~
如有笔误或者了解谬误,欢送交换~
Thanks
- Android API reference
- Build a Responsive UI with ConstraintLayout
- ConstraintLayout
- Build a Responsive UI with ConstraintLayout
- Guideline
- Understanding the performance benefits of ConstraintLayout
- LinearLayout
- 绝对布局
- FrameLayout
- GridLayout
- 表格
- The curious BlinkLayout
- 每日一问:浅谈 onAttachedToWindow 和 onDetachedFromWindow
- ondraw() 和 dispatchdraw()的区别