viewAndroid知识Android技术知识

实战-ConstraintLayout新布局

2016-10-22  本文已影响1311人  坠入海里

在今年,2016年的Google i/o 大会上,Google推出了Android studio2.2,其中包含了为Android界面布局推出的最新的约束型布局ConstraintLayout,接触过iOS界面开发的朋友,可以认为这是Google为Android推出的AutoLayout布局。因为这方面的资料还不是很多,大部分的资料都是Google官方介绍翻译,没有具体用在项目里的实例,在此正好公司项目中遇到一个问题,用ConstraintLayout解决了,期间也遇到点困难。在这里我写出来,希望可以帮助到大家,也为了推广这种布局,希望大家可以使用。

如图,需求是一个时间轴控件,使用ListView实现。

每个adapter中包含:

  1. 一个ImageView,表示时间轴中的进度点
  2. 进度点,上面的线line_top(View)
  3. 进度点,下面的线line_bottom(View)
  4. 两个TextView,分别是进度说明,和时间
  5. 一条横向的线line(View)
最终做出来的效果图如下
最终效果图

现在我们分析一下这个效果图:

上面这6点是布局中需要注意的,不变的部分很容易,我们只需要关注变的部分,再精减一下:

  1. 进度点下面的线高度,可变;

再剖析一下,上面3点中,2,3两点很容易在RelativeLayout中实现,但是1的高度,是根据TextView的行高来实现的,既1的变化,依据2的变化。

可惜的是,我在用RelativeLayout,实现这3点的时候,发现下部的线高度不能自动保持跟第一个TextView,一样的高度,只能保持一行的高度,个人认为是TextView调用setText()方法时,通知了TextView的重新绘制,但是下部分的线没有重新绘制,这也许是RelativeLayout的不足之处。个人愚见,还有待探究。

因为我想用xml就把布局关系完成,不需要再代码里面在操作布局关系,通知绘制,所以就想到了新布局,ConstraintLayout约束布局。
下面开始:

第一步:创建布局,摆放控件

转换成为ContraintLayout


转换成为ContraintLayout

把需要的控件都放进去,如下图,大概摆好


大致位置

现在我们看到的大概的位置,没有添加任何约束。

第二部:添加约束

对于约束,每一个控件至少水平方向,垂直方向各有一个约束,才能使视图不会报错,想让自己的布局完美展现在手机上,我们应该消除所有警报。

Paste_Image.png

首先我们知道line_top位置和长度都是固定的,这里我让它距离屏幕左边30dp,高度设置为12dp。鼠标放在line_top上,会出现4个空心圈。这4个空心圈代表着line_top,上下左右都没有设置约束,我们想让line_top距离左边30dp,鼠标点击左边的空心圈,按住不松,拖至屏幕左边沿,会出现如下图,松开就设置了一个约束,

line_top左边到屏幕左边沿约束

这时我们观察,界面左边栏。如下图:

按照上面的操作,再把line_top上方设置一个约束,距离顶部0dp。这样line_top这条线就被固定住了。

现在我们之后所有的控件都直接依赖或者间接依赖这个line_top控件,进行布局。

下面我们将进度点ImageView这个控件,与line_top中心对其,如下图:

ImageView中心对其line_top

ImageView左右两边都设置约束,分别对line_top左右两边对齐,这时进度点ImageView自动中心对齐了line_top。很简单,但是我一开始就想不到,也是试了半天才知道要这么设置。
这时,我们要开始布局下一个控件了么?不,我们应该检查刚刚的Imageview有没有满足下面这条准则:
对于约束,每一个控件至少水平方向,垂直方向各有一个约束,才能使视图不会报错,想让自己的布局完美展现在手机上,我们应该消除所有警报。

显然这个进度点在垂直放向缺少一个约束,我们让他上方距离line_top有3dp的距离

ok,此时我们设置下一个控件,第一个TextView,TextView上方与进度点ImageView上方水平对齐,�我们拉住TextView上方的空心圈,移到ImageView的上方,送手,就完成了水平对齐
再设置左边到ImageView右边距离为16dp。完成如下图:

第一个TextView约束

接下来我们让第二个TextView完成它的约束,我就不细讲了,相信你们也明白怎么用了,如下图:

第二个TextView约束

下面是重点了,line_bottom的约束我们怎么设置:

line_bottom未完成的约束

这里我们看到有两个约束,一个是左边与line_top左边对齐,这样因为line_top已经与ImageView中心对齐,所以line_bottom这样也会跟ImageView中心对齐,但是我们知道line_bottom长度不固定,是可变的。选中line_bottom,接下来,我们看下图:

line_bottom的高度设置

如下3种模式:

Fixed: 此选项允许你指定控件的高和宽. AnySize: 此选项让控件占用所有可用空间以适应约束. 换句话说, 这更像是匹配约束. 与 match_parent 不同, 后者占用父 View 的所有可用空间. Wrap Content: 此选项仅扩展至所含元素(如 text 或者 drawable)填充满 widget.

显然我们要把它切换为AnySize。

再让line_bottom下方与横向line距离为0dp,完成约束,如下图:

line_bottom完整的约束

最后我们只剩下一个横线line,没有设置约束了,一样他也是可变的,设置为AnySize,添加约束。如图:

横向line的约束

完成了么?
看起来好像没有问题了。不过我们是不是忘了第一个TextView内容很多,可能会出现几行的情况。
这里我们还需要给第一个TextView的右边设置一个到屏幕右边沿的约束,我们设置为距离右边50dp,同时TextView的宽也要设置为AnySize,因为他是可变的。
最后所有约束设置完成,我们看一下完整版的图:

完整约束图

我们可以试验一下是否可以自动适应高度。我们向第一个TextView中写入一段话,将控件撑大点,效果如下图:

效果图

可以看到效果很不错。到此为止,解决问题,同时ConstraintLayout可以完成很复杂的布局,减少布局的层次,Android布局层次越深,带来的性能损耗越大,当然对于目前Android手机性能不是问题,但是作为一个进益求精的开发者,谁不希望用最少的资源,完成最酷的效果呢?

上一篇下一篇

猜你喜欢

热点阅读