使用 ConstraintLayout 构建一个响应式的 UI
LinoJohnsto
8年前
<p>其实AS2.2的预览版本早就出来了,ConstraintLayout也出来由于一段时间了,由于预览版本稳定性的原因一直没敢用,所以ConstraintLayout迟迟没去学习,最近AS的稳定版终于发布,我也随之更新,不得不说AS现在越来越强大了,最近学习ConstraintLayout看到官方一篇很不错的文章,基本包含了ConstraintLayout所有的点,相信看完之后对ConstraintLayout也会有一个全面的了解,不得不说官方的资料才是最好的资料,英语比较好的同学可以直接看原文,本人第一次翻译,有不对的地方请多多指出。</p> <p>ConstraintLayout 不需要使用嵌套布局就可以让我们去构建一个大而复杂的布局,他与 RelativeLayout 很相似,所有在里面的View的布局方式取决于View与View之间的关系和父布局。但是他比 RelativeLayout 更灵活,并且在Android Studio's Layout Editor中可以很容易的去使用。</p> <p>ConstraintLayout 的所有工作都可以使用布局编辑器的可视化工具中完成,因为布局API和布局编辑器对此专门构建的。因此你可以完全通过拖拽的方式去构建一个使用了 ConstraintLayout 的布局,而不用直接在XML中编辑。</p> <p><img src="https://simg.open-open.com/show/0ab3748016e27e4001e1aed07fe79db4.png"></p> <p style="text-align: center;">图1</p> <p>ConstraintLayout 在API库中是可用的,最低兼容至Android2.3,新的布局编辑器可以在Android Studio2.2及其以上使用。这篇文章的目的是为在Android Studio中去构建一个基于 ConstraintLayout 的布局提供一个指南,如果你想了解更多的关于布局编辑器的信息,请看 <a href="/misc/goto?guid=4959716803486490311" rel="nofollow,noindex">Build a UI with Layout Editor</a> (注:需KX上网)</p> <h2><strong>一、Constraints 概述</strong></h2> <p>在 ConstraintLayout 中,如果你要定义一个View的位置,那么你必须添加两个或者更多的约束,每一个约束代表了一个连接或者对齐另外一个View、父布局、一个可视化的引导线(辅助线,对用户不可见的,后面文章中会有说明),每一个约束都定义了View在水平或垂直方向的位置,因此每一个View与轴线(垂直和水平方向)都至少应该有一个约束。</p> <p>当你拖一个View到布局编辑器中,如果没有任何约束,他会待在你鼠标离开的位置,然而这个仅仅是让编辑的时候更容易而已,如果这个View没有任何约束,当你运行应用到在设备上,他将会被绘制到左上角[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</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/96a64660b3b253c469aca9aa4cede735.png"></p> <p style="text-align: center;">图3</p> <p>尽管缺少了约束也不会造成编译错误,布局编辑器将会在工具栏上显示有一个缺少约束的错误,如果想去看这些错误和其他警告请点击 <strong>Show Warnings and Errors</strong> (如下图)。为了帮助我们去避免出现缺少约束的错误,布局编辑器的 <strong>Autoconnect and inferconstraints</strong> (如果没有开启,则需要我们去开启,下图工具栏第二排的第二个和第四个图标对应这两个功能)将会自动加约束。</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/d830aba84e6a331e872ee68e74378d56.png"></p> <h2><strong>二、添加ConstraintLayout到我们的项目中</strong></h2> <ol> <li>确保你有最新的Constraint Layout库 <ul> <li>点击 <strong>Tools > Android > SDK Manager</strong></li> <li>点击 <strong>SDK Tools</strong> tab</li> <li>展开 <strong>Support Repository</strong> ,然后勾选 <strong>ConstraintLayout for Android</strong> 和 <strong>Solver for ConstraintLayout</strong> 。勾选 <strong>Show Package Details</strong> ,注意你下载的版本</li> <li>点击 <strong>OK</strong></li> <li>添加ConstraintLayout库到你的build.gradle文件中 <pre> dependencies { compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8' }</pre> 你下载的这个库的版本可能会更高,确保与你之前下载的版本匹配即可</li> <li><strong>Sync Project with GradleFiles</strong></li> </ul> </li> </ol> <p>注:将你的支持库更新到最新即可。</p> <h2><strong>三、转换已经存在的布局成ConstraintLayout</strong></h2> <ol> <li>打开你的布局文件,切换到Design tab</li> <li style="text-align: center;">在 <strong>Component Tree</strong> 窗体中,右击布局文件,然后点击 <strong> Convert <em>layout</em> to ConstraintLayout </strong> (如图4)。<br> <img src="https://simg.open-open.com/show/114c28ccb38b06775cb93e1dd8dfc076.png"> <p style="text-align: center;">图4</p> </li> </ol> <h2><strong>四、创建一个新的布局</strong></h2> <ol> <li>新建一个布局文件</li> <li>输入布局文件的名字,将布局的根元素改为 android.support.constraint.ConstraintLayout</li> <li>最后点击完成</li> </ol> <h2><strong>五、添加一个约束</strong></h2> <p>拖一个View到布局编辑器中。当你添加了一个View到 ConstraintLayout 中,他的四个角对应着的四个小矩形框是控制大小的,每一条边有四个圆形的约束控制点。</p> <p>单击View选中,然后单击并按住一个约束控制点拖拽这条线到一个可用的锚点(其他View、Layout的边缘或者引导线),当你松开,这个约束将会被创建,两个View也将被默认的margin隔开。</p> <p>当你创建一个约束的时候,一定要记得下面几点规则:</p> <ul> <li>每一个View必须有两个约束:一个水平的,一个垂直的</li> <li>只有约束控制点和另外一个锚点在同一平面才能创建约束(也就是说将要创建的约束的View和锚点View属于同一级)。因此一个View的垂直平面(左侧和右侧)只能被另一个的垂直平面约束,基线只能被其他基线约束。</li> <li>一个约束控制点,只能被用来创建一次约束,但是可以在同一锚点创建多个约束(来自不同的View)</li> </ul> <p>如果你想要删除一个约束,先选举中View,然后点击需要删除的约束控制点即可。</p> <p>如果你在一个View中加了一个相对约束,约束线看起来弯弯曲曲的和弹簧差不多,表示相对的 <strong>力</strong> ,当View被居中显示,并且其大小被设置成"fixed" 或者 "wrap content",这种视觉效果就会越明显。如果你想这个View的大小与适应约束,只需将View的大侠送改为"any size"(0dp),如果你想保持这个View当前的大小,但是不然View居中显示,只需调整约束的偏移率(constraint bias)即可。</p> <p>有很多种方式去约束一个View,但是下面的约束类型提供了一个基本的构建块。</p> <h2><strong>六、Parent constraint(父布局约束)</strong></h2> <p>View的侧面链接到布局相应的边缘,图5中ImageView的左侧面连接到父布局的左边缘。</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/060bb72157cc7503a63187f324fe1c41.png"></p> <p style="text-align: center;">图5</p> <h2><strong>七、Position constraint(位置约束)</strong></h2> <p>可以定义两个View在水平或者垂直方向上出现的顺序,在图6中Button顶端距离ImageView底部24dp。(用margin的表示这个约束)</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/5057fdf6394a0cf7a90491bd13bad7df.png"></p> <p style="text-align: center;">图6</p> <h2><strong>八、Alignment constraint(对齐约束)</strong></h2> <p>可以对齐两个View的同一边缘,在图7中Button的左边缘与ImageView的左边缘对齐。</p> <p>你也可以通过拖动View来控制对齐的偏移量,图8 展示了Button左边缘与ImageView左边缘对齐之后有24dp的偏移量,偏移量通过View的margin控制。</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 style="text-align: center;"><img src="https://simg.open-open.com/show/1d680a9e483d8d6ee6dc084052af0587.png"></p> <p style="text-align: center;">图8</p> <h2><strong>九、Baseline alignment constraint(基线对齐约束)</strong></h2> <p>可以对齐两个View的文本基线,在图9中,Textview的第一行基线与Button中的文本对齐。</p> <p>要想创建一个基线约束,需要移动你的鼠标在基线控制点的上面,然后停留2秒钟,直到控制点开始闪烁,然后点击拖拽这条线到另一条基线。</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/9a857ca71beb1c04e653e373cd57f213.png"></p> <p style="text-align: center;">图9</p> <h2><strong>十、Constrain to a guideline(约束到一个引导线(辅助线)</strong></h2> <p>你可以添加一个水平和垂直方向上的引导线,这可以当做你的附加约束。你在布局内可以定位这个引导线,dp和百分比作为单位均可。</p> <p>想要创建这个引导线,在工具栏点击 <strong>Guidelines</strong> (如下图),然后点击 <strong>Add Vertical Guideline</strong> o或者 <strong>Add Horizontal Guideline</strong> 即可。</p> <p>拖动引导线中间的圆即可定位引导线的位置。</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/f98e9f89168ba076e61130f7a2f61e62.png"></p> <p>注:引导线对用户是不可见的。</p> <h2><strong>十一、Use Autoconnect and Infer Constraints(使用自动连接和约束推断)</strong></h2> <p>Autoconnect 为添加进布局的View自动创建两个或者多个约束,Autoconnect 默认被禁用,你可以通过点击编辑器工具栏中的 <strong>Turn on Autoconnect</strong> (一个有点像磁铁的图片)开启他。</p> <p>当你开启了 <strong>Autoconnect</strong> ,当你添加新的View到布局之后 <strong>Autoconnect</strong> 就会自动创建约束,他不会为已经存在的View创建约束。如果你拖动View一次,约束就值将会改变,但是之前的约束本身不会被改变。所以如果你想重新去定位View,那么你必须删除之前的约束。</p> <p>或者,你可以点击 <strong>Infer Constraints</strong> (一个有点像电灯的图标)去为布局中所有的View创建约束</p> <p>Infer Constraints扫描整个布局为所有的View决定一套最有效的约束,因此他可以创建两个距离很远的View之间的约束。然而 <strong>Autoconnect</strong> ,只能为新添加进布局的View创建约束,并且他创建的约束仅仅只能是距离最近的元素。在这两种情况下,你可以随时通过点击约束控制点去删除约束然后创建新的约束去修改他。</p> <h2>十二、Adjust the view size(调整View的大小)</h2> <p>你可以使用View每个角的控制点去调整其大小,但是这样做只是把宽高写死,这样做不能适应不同的内容和不同的屏幕大小,我们应该避免这样去使用。为了选择一个动态的大小模式或者定义一个更具体的尺寸,请单击并打开编辑器右侧的 <strong>Properties</strong> 窗口,如图10。</p> <p>灰色的矩形区域,代表选择的View,矩形的的符号代表宽和高。</p> <ul> <li><strong>(>>>)Wrap Content</strong> :View的大小与其内容适配</li> <li><strong>(有点像弹簧的图标)Any Size</strong> :View大小刚好匹配其对应的约束,他的实际值是0dp,表示这个View没有期望的尺寸,但是他渲染后的大小将会匹配其约束。</li> <li><strong>(直线)Fixed</strong> :View的大小的是固定的</li> </ul> <p>点击符号即可在上面三种模式中互相切换。</p> <p>注意:你不应该在ConstraintLayout中使用match_parent,而是使用0dp</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/0ae89a7cfc113be0ec501c2c50346cbb.png"></p> <p style="text-align: center;">图10:1.View的大小 2.margin 3.constraint bias</p> <h2><strong>十三、Adjust the constraint bias(调整约束偏移率)</strong></h2> <p>当你为一个View的两测添加了约束,默认的,View将变成两个锚点的中心,当View居中的时候,偏移率就是50%,你也可以拖拉constraint bias 滚动条去调整(如图10的第三点)</p> <p>十四、Adjust the view margins(调整View的margin)</p> <p>为了确保左右的View都被均衡的隔开,点击工具栏的 <strong>Margin</strong> (如图11)去为新添加进布局的View选择一个默认的margin值,Button将会显示你当前选择的值,你做的更改将应用于之后你新添加的View。</p> <p>你也可以通过点击图10 线上的数字去更改margin的值。</p> <p>工具中提供的margin值全是8的倍数,帮助你的View与Material Design的推荐的 <a href="/misc/goto?guid=4959716840333001957" rel="nofollow,noindex">8dp的方形网格</a> 保持一致</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/809051b721d954a12e3761f5c719ca76.png"></p> <p style="text-align: center;">图11</p> <p>翻译end</p> <p> </p> <p>来自:http://www.jianshu.com/p/f61227a2775f</p> <p> </p>