使用约束布局(ConstraintLayout)构建灵活的UI

cymandroid 8年前
   <p>Android团队为开发者带来了ConstraintLayout,一种构建于弹性Constraints(约束)系统的新型Android Layout,据说它将大大改变今后的Android布局界面开发方式,据说也许以后Android开发没有那么多布局需要学习,只需要熟悉这一种布局即可。前两天Android studio 2.2正式版发布了,更多的Android 开发者会接触并(可能)使用这个布局。</p>    <h2><strong>使用约束布局(ConstraintLayout)构建灵活的UI</strong></h2>    <p>约束布局允许你在相同视图层级中(不是相互层叠的视图组合)制作大而复杂的布局。它类似于相对布局那样所有的视图位置是根据子布局或父布局决定的,但是它比相对布局更加灵活,并且在Android studio布局编辑器中更加易用。</p>    <p>你可以直接在布局编辑器的可视化工具中做约束布局中所做的所有事,因为布局API和布局编辑器已经做了特地融合。所以你可以通过拖拽使用约束布局构建你的布局,而不需要再去编辑XML文件。</p>    <p><img src="https://simg.open-open.com/show/0ab3748016e27e4001e1aed07fe79db4.png"></p>    <p style="text-align: center;">图1,布局编辑器中的约束布局</p>    <p>约束布局可以在兼容Android2.3(API 9)或者更高的API库中使用,而新的布局编辑器则在Android studio2.2中可用。</p>    <p>这篇文章提供了一个在Android studio中使用约束布局构建一个布局的指导。如果你想要了解关于布局编辑器更多信息,在这个 <a href="/misc/goto?guid=4959716803486490311" rel="nofollow,noindex">Build a UI with Layout Editor</a> Android studio指导中查看.</p>    <h2><strong>约束概述</strong></h2>    <p>为了定义在约束布局中视图的位置,你必须为视图添加两个或更多约束条件。每个约束代表了和另个视图、父布局或不可见指引线的联系或对齐。每个约束限定了视图是沿着垂直轴还是水平轴的位置,所以每个视图必须在每个轴最少拥有一个约束,但经常需要更多。</p>    <p>当你往布局编辑器中拖拽一个视图时,它会停留在你扔下它的位置,即使它没有任何约束。然鹅,这只是为了使编辑更简单。当一个视图没有任何约束时,你在设备上运行起来后,它会被绘制在左上角[0,0]的位置。</p>    <p>在图2里面,布局在编辑器中看起来不错,但是对于TextView B没有对其进行竖直方向上的约束。当这个布局被绘制到设备上时,TextView B会在水平方向上水平与ImageView的左右边缘对齐,但是出现在屏幕的顶部,因为它没有数值方向上的约束。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/15440966beb20e9d7aa1b02b1443c4ae.png"></p>    <p style="text-align: center;">图2,缺少垂直方向约束的TextView B</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/96a64660b3b253c469aca9aa4cede735.png"></p>    <p style="text-align: center;">图3,TextView B现在在垂直方向上约束于ImageView</p>    <p>虽然缺少约束条件不会造成编译错误,但布局编辑器会在ToolBar中展示为一个错误指示缺少约束条件。要查看错误或者其他警告,可以点击 Show Warnings and Errors .为了帮你避免忽视约束条件,布局编辑器会使用 <a href="/misc/goto?guid=4959716803569979771" rel="nofollow,noindex">Autoconnect and infer constraints</a> 功能为你自动添加约束。</p>    <h2><strong>在你的工程中添加约束布局</strong></h2>    <p>要在你的工程中使用约束布局,步骤如下:</p>    <p>1,确定你有最新的Constraint Layout library;</p>    <pre>  1.点击Tools > Android > SDK Manager.  2.点击 SDK Tools栏.  3.展开Support Repository,然后检查ConstraintLayout for Android,      并且Solver for ConstraintLayout.      检查Show Package Details,注意你下载的版本(你需要的是下面这个)。  4.点击OK.  5.在你的module-level build.gradle文件里面添加ConstraintLayout library作为依赖:</pre>    <pre>  dependencies {      compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'  }</pre>    <p>你下载的库版本或许会更高,所以确保你指定的版本跟第三步中的版本相匹配。</p>    <pre>  6.在toolbar或者sync提示中,点击Sync Project with Gradle Files.</pre>    <p>现在你可以使用ConstraintLayout构建布局了.</p>    <h2><strong>转换布局</strong></h2>    <p>按照以下步骤,将现有的布局转换为约束布局:</p>    <pre>  1.在Android Studio打开你的布局,点击编辑器窗口最下面的Design标签.  2.在Component Tree窗口,右键布局,然后点击Convert layout to ConstraintLayout.</pre>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/114c28ccb38b06775cb93e1dd8dfc076.png"></p>    <p style="text-align: center;">图4,转换为ConstraintLayout的功能菜单</p>    <h2><strong>新建布局</strong></h2>    <p>以下步骤开始新建一个约束布局文件:</p>    <pre>  1.在Project窗口任意位置右键,然后选择File > New > XML > Layout XML.  2.输入布局文件名字,然后输入"android.support.constraint.ConstraintLayout"   作为布局根标签.  3.点击完成.</pre>    <h2>添加约束</h2>    <p>首先从Palette窗口拖拽一个视图到编辑器。当你在约束布局中添加一个视图时,它显示为一个每个角都带有正方形手柄,并且每边都带有的环形手柄的边框</p>    <p>点击选中视图,然后点击并按住约束手柄之一并拖动线到可用的锚点(另一个视图的边缘,布局的边缘,或者一条引导线)。当你释放的时候,约束生成,带有默认的 <a href="/misc/goto?guid=4959716803652413556" rel="nofollow,noindex">a default margin</a> 分离两个视图。</p>    <p>video1</p>    <p>新建约束时,记住以下规则:</p>    <pre>  *每一个视图至少有两个约束:一个垂直方向,一个水平方向。  *只有在约束手柄和锚点在同一平面时才能新建约束,      所以一个视图的垂直平面(左右侧)只能被约束到另一垂直平面。      并且基线只能约束到其他基线。  *每个约束手柄只能被用于一个约束,但是可以对同一个锚点创建多个约束(从不同的视图)</pre>    <p>选中一个视图然后点击约束手柄,可以删除一个约束。</p>    <p>如果你在一个视图中添加对立的约束,约束线变成像弹簧一样的波浪来表示反动势力,就像 <a href="/misc/goto?guid=4959716803737135212" rel="nofollow,noindex">video2</a> 中展示的一样。</p>    <p>当视图的大小被设为『fixed』或者『wrap content』时,这种情况下视图位于约束条件中心时,效果最为明显。如果你希望视图撑开尺寸以满足约束条件,改变尺寸至"any size";或者如果想保持目前的大小,单移动视图,使其不居中,可以调整约束偏置。</p>    <h2><strong>有许多方式可以来约束一个视图,但下面的约束类型提供了基本构建模板</strong></h2>    <h3><strong>父约束</strong></h3>    <p>视图的侧面连接到相应布局的边缘。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/060bb72157cc7503a63187f324fe1c41.png"></p>    <p style="text-align: center;">图5</p>    <p>图5中,视图的左边被连接到父布局的左边缘.</p>    <h3><strong>位置约束</strong></h3>    <p>给两个视图定义出现的次序,垂直或者水平。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/5057fdf6394a0cf7a90491bd13bad7df.png"></p>    <p style="text-align: center;">图6</p>    <p>图6中,Button被约束于ImageView下边缘24dp处,</p>    <h3><strong>对齐约束</strong></h3>    <p>对齐视图的边缘到其他视图的同意边缘。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/4c3c1abde53324b50e947ee5f6d82ea7.png"></p>    <p style="text-align: center;">图7</p>    <p>图7中,Button的左边缘被对齐到ImageView的左边缘。</p>    <p>你可以从约束向里拖动视图校准偏移。比如,在</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/1d680a9e483d8d6ee6dc084052af0587.png"></p>    <p style="text-align: center;">图8</p>    <p>图8中,展示了相同的Button偏移了24dp,这是通过约束视图边界限定的偏移。</p>    <h3><strong>基线对齐约束</strong></h3>    <p>对齐视图的文本基线到其他视图的文本基线。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/9a857ca71beb1c04e653e373cd57f213.png"></p>    <p style="text-align: center;">图9</p>    <p>图9中,第一行的TextView被对齐到Button的text。</p>    <p>将鼠标悬停在基线手柄两秒钟,直至手柄闪烁白色。然后点击并拖出一条线到另一个基线,创建出一个基线约束。</p>    <h3><strong>引导线约束</strong></h3>    <p>在想附加约束的地方可以添加水平或垂直的引导线,你可以在布局内部基于相对于布局边缘的dp或是百分比定位引导线。</p>    <p>在toolbar中点击Guidelines,然后再点击Add Vertical Guidelin或者Add Horizontal Guideline创建引导线。</p>    <p>点击引导线边缘的环形toggle,切换用于定位引导线的测量值(从布局边缘的百分比或dp单位)</p>    <p>引导线不会对用户可见。</p>    <h3><strong>使用自动连接并推断约束</strong></h3>    <p>自动连接是一个持久的模式,会为你添加到布局中的每一个视图自动创建两个或多个约束,默认为不可使用状态。你可以在布局编辑器的ToolBar中点击Turn on Autoconnect来启用。</p>    <p>当其可用时,你添加的每个视图都会为你自动创建约束。它不会对布局中已经存在的视图创建约束。一旦约束创建,如果你想拖拽视图,约束不会改变。所以如果你想明显的重新定位视图的位置,必须先删除约束。</p>    <p>或者,你可以点击Infer Constraints为布局中所有的视图创建约束。</p>    <p>推断约束(Infer Constraints)是一次性的动作,以扫描整个布局以确定所有视图最有效的约束,因此它可能创建彼此相隔很远之间的约束。然鹅,自动连接(Autoconnect)创建的约束只是在你添加的视图上,并且它创建的约束只会在附近的元素上。这两种情况下,你可以随时通过点击约束手柄删除修改约束,然后创建一个新的约束。</p>    <h3><strong>调整视图大小</strong></h3>    <p>你可以用视图每个角的额手柄来改变视图的大小,但是你应该规避对大多数视图做宽度和高度的硬编码,应为硬编码视图大小无法适应不同的内容和屏幕尺寸。点击视图,打开编辑器右侧的Properties窗口,选择一种动态调整大小的模式或者定义更多具体的尺寸。如</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/0ae89a7cfc113be0ec501c2c50346cbb.png"></p>    <p style="text-align: center;">图10,Properties窗口包括①视图尺寸,②边距,③约束偏置</p>    <p>图10,Properties窗口包括①视图尺寸,②边距,③约束偏置,在窗口顶部是视图检查器。</p>    <p>灰色方框代表选中的视图,方框内的符号(卧槽这个符号我就用字符代替了哈ಠ౪ಠ)表示宽度和高度值可以用如下方式设置:</p>    <pre>  * >>>Wrap Content:视图自适应为其内容大小。  * |-/|/|/-|Any Size:视图按照匹配的约束适应大小。      视图没有指定明确的尺寸,实际值为0dp,但是它按照满足需求的约束调整了大小。      然而,如果给定的尺寸只有一个约束,那么该视图自适应其内容。      另一种思路可以认为它是"match constraints"(等同于match_parent)。      因为它会在满足每个约束和边距条件后,尽可能的扩展视图。  *|---|Fixed:在文本框中指定尺寸,或者在编辑器中调整视图大小。</pre>    <p>点击符号,可在这些设置之间切换。</p>    <p>Note:在约束布局中的所有视图,都应该使用match_parent,而不是 "Any Size" (0dp)。</p>    <h3><strong>调整约束偏置</strong></h3>    <p>当你在一个视图(相同尺寸的视图大小为"fixed"或"wrap content")两侧添加一个约束时,默认情况下该视图成为两个锚点的中心,偏置为50%。你可以通过在Properties窗口中拖动偏置滑块或者直接拖动视图来调整偏置,如 <a href="/misc/goto?guid=4959716803813361196" rel="nofollow,noindex">video5,调整约束偏置</a> .</p>    <p>如果你想让视图满足约束的情况下撑开大小,切换视图尺寸至任何大小"any size"。</p>    <h3><strong>调整视图边距</strong></h3>    <p>为了确保你所有的视图是均匀分布,点击ToolBar中的Margin 8,对你添加进布局的视图选择默认边距。这个按钮会变为显示你当前边距的选项,你对默认边距的修改只会应用于修改之后添加的所有的视图。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/809051b721d954a12e3761f5c719ca76.png"></p>    <p style="text-align: center;">图11,ToolBar的Margin按钮,点击调整默认边距</p>    <p>你可以通过点击在Properties窗口里面代表约束线上面的数字,来控制每个视图的边距(图10中,每个边距被设置为16dp).</p>    <p>工具提供的所有边距为8dp的原因是为了让你的视图跟随Material Design大法的</p>    <p> </p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/3362d69fd01f</p>    <p> </p>