使用 ConstraintLayout 来设计 View

ShaniDLC 7年前
   <h3><strong>1. 概要</strong></h3>    <p><img src="https://simg.open-open.com/show/5d52bf32c44cb83a282c0944e8a9800e.png"></p>    <p>ConstraintLayout 是 Android Support 库中可用的一种新型的建立在灵活的约束系统上的布局。在文末你将学会利用布局编辑器来构建相对复杂的布局。</p>    <ul>     <li> <p>ConstraintLayout使用新的布局管理器</p> </li>     <li> <p>创建约束来实现灵活高效率的布局</p> </li>     <li> <p>新的布局编辑器的多种特性。</p> </li>    </ul>    <p>需要的环境:AndroidStudio 2.2</p>    <p><strong>2. 获取示例代码</strong></p>    <p>或者从github上clone代码:</p>    <p>$ git clone https://github.com/googlecodelabs/constraint-layout.git</p>    <p>constraint-layout 的仓库包含一个项目:</p>    <p> </p>    <pre>  <code class="language-java">constraint-layout-start— Project that contains the layouts that you'll build upon in this codelab.</code></pre>    <p><strong>3. 运行示例代码</strong></p>    <p>首先,来看一下运行后的程序是怎样的。请确保您的Android Studio在版本2.2以上。</p>    <ul>     <li>进入 <strong>File</strong> > <strong>New</strong> > <strong>Import Project</strong> 并且从之前下载的示例程序中选择路径 constraint-layout-start.</li>     <li>点击 <strong>Gradle sync</strong> 按钮.</li>     <li>从项目面板中打开 res/layout/activity_main_done.xml.</li>     <li>选择 tab Design 可以看到最终的布局.</li>     <li>在 UI Builder的左上方变换虚拟设备等按钮可以看到不同因素影响下渲染的布局. <p><img src="https://simg.open-open.com/show/0c3dae841f9c881cfa6a32ecc45a96cb.png"></p> </li>    </ul>    <p><strong>4. 约束系统概览</strong></p>    <p>布局引擎使用为每个小部件指定约束来确定它们在布局中的位置。 您可以手动或通过Android Studio布局编辑器中的推算自动指定约束。 为了更好地理解约束,让我们看看所选窗口小部件上的基本处理。</p>    <p><strong>约束</strong></p>    <p>约束可帮助您保持小部件对齐。 您可以使用锚点(例如下面描述的约束句柄)来确定各个窗口小部件之间的对齐规则。 例如,将约束从按钮2的左约束句柄(参见下面的图A)设置到按钮1的右约束句柄意味着按钮2小部件将位于按钮1的右边56dp。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/35188fb00fc3b9fb28039e07a192b6cb.png"></p>    <p><strong>不同类型的句柄</strong></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/21878793081b6a876ae43f22bbd32731.png"></p>    <p>在这张图上,我们可以看到不同类型的句柄。</p>    <p><strong>Resize Handle</strong>:类似于你可能已经使用的其他设计/绘制应用程序,</p>    <p><strong>Resize Handle</strong>允许您调整窗口小部件的大小。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/99a8ebe4d5ada56e4abacb2dfedc9d50.png"></p>    <p><strong>Side Constraint Handle: </strong>侧边约束句柄(每个小部件侧面的圆形)允许您指定该窗口小部件的位置。 例如,您可以使用窗口小部件的左侧约束句柄总是在另一个窗口小部件的右侧的24dp。 这些在整个编码表中也被称为锚点。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/924dedda9eb89c0ab8f6a268c4558e13.png"></p>    <p><strong>Baseline Constraint Handle:</strong></p>    <p>基线约束句柄帮助您对齐任何两个小部件的文本字段,而不考虑小部件大小。 对于当你有两个不同大小的小部件,但希望里面的文本是对齐的情况是很有帮助的。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d979ead42d02ee56f422f748888e69e2.png"></p>    <p><strong>约束系统的规则</strong></p>    <p>布局中的窗口小部件的锚点可以连接到另一个窗口小部件的任何锚点,但以下情况除外:</p>    <p>不能连接不同类型的锚点:</p>    <ul>     <li>锚点在不同轴线上,如左,顶锚点连接。</li>     <li>基线约束句柄只能限制到另一个基线。<br> 不允许连接导致循环的锚点。</li>    </ul>    <p><strong>5. 构建初始应用程序</strong></p>    <p>准备工作:</p>    <ul>     <li> <p>从左侧导航栏中打开 res / layout / activity_main_start.xml 。</p> </li>     <li> <p><strong>包括对约束布局的依赖</strong><br> 约束布局作为一个单独的支持库,可以在所有Android版本(Android 2.3(Gingerbread)以上)运行。<br> 应用程序已经在app / build.gradle中包含了该依赖关系。 对于您打算使用ConstraintLayout构建的应用程序,添加以下编译依赖关系:</p> <pre>  <code class="language-java">dependencies {  ...  compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha2'  }</code></pre> </li>     <li> <p>导航到 res/layout/activity_main_start.xml</p> </li>    </ul>    <p>布局的XML版本已经在codelab项目中包含一个空的ConstraintLayout元素。 ConstraintLayout是从头开始构建的,以便与UI Builder结合使用,因为我们相信它可以提供更直观和更强大的体验。 尽管如此,您仍然可以访问并可以编辑相应的XML。(这间接告诉我们他是一个ViewGroup)</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <android.support.constraint.ConstraintLayout      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">    </android.support.constraint.ConstraintLayout></code></pre>    <ul>     <li> <p>切换到(在编辑器窗口底部显示为选项卡的)设计(Design)视图。(好拗口)</p> </li>    </ul>    <p style="text-align:center"><img src="https://simg.open-open.com/show/3d6c63e3cdc07de6ff8111a0e127f6ce.png"></p>    <ul>     <li> <p><strong>为布局添加一个ImageView</strong></p> <p>第一个任务是将ImageView添加到布局。 在设计窗口中,在面板上找到ImageView并将其拖动到布局中。</p> </li>    </ul>    <p><img src="https://simg.open-open.com/show/55ef4bf11c52d34b224cbaa32541234c.png"></p>    <p>一旦ImageView被拖动到布局里,UI Builder会要求使用一个资源。 constraint-layout-start sample已经包括使代码方便实现的资源。 继续选择@drawable/singapore资源。</p>    <p>选择后,ImageView将出现在布局上,您可以单击并按住角落以调整图像大小,如“约束系统概述”中所述。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/cbd263102fc6db42d9cbaf85877a8fea.gif"></p>    <ul>     <li> <p>在布局里添加TextView</p> <p>现在,从面板里拖一个TextView到布局里。</p> </li>    </ul>    <p><img src="https://simg.open-open.com/show/f89e4553cb66ebe992e070308263b2ea.png"></p>    <p>我们在UI Builder中看到一些警告,这是由于缺少ImageView上的contentDescription属性,以及对TextView硬编码文本。 内容描述属性对于构建可访问应用程序很重要。</p>    <p>对于这个codelab,让我们使用一个已经可用的资源@ string/dummy作为属性。</p>    <p>在右侧,“检查器”窗格允许您更改所选窗口小部件的各种属性。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/c61bfbd2002214a5c0589e14bbd6e3c1.png"></p>    <ol>     <li> <p>选择ImageView并将@ string / dummy添加到其contentDescription属性中。</p> </li>     <li> <p>在“检查器”窗格中,还可以查看ImageView的其他属性。 出于此Codelab的目的,将scaleType更改为centerCrop。</p> </li>     <li> <p>接下来,我们选择TextView并使用Inspector窗格将TextView的文本值修改为@ string / singapore。</p> </li>    </ol>    <p>此时,我们在布局中有两个视图。 在下一节中,我们将了解如何在视图之间创建约束。</p>    <p>前边都是小菜一碟,接下来才是本文的重点,要点,新的知识点。</p>    <h2><strong>此处是高贵的分割线。</strong></h2>    <p>内容主要涵盖了:</p>    <ul>     <li> <p>创建手动约束</p> </li>     <li> <p>使用Autoconnect创建约束。</p> </li>     <li> <p>使用推理创建约束。</p> </li>    </ul>    <p><strong>6.创建手动约束</strong></p>    <p>操作方法:要创建约束,您需要在给定的句柄上单击并按住鼠标,然后将其拖动到另一个窗口小部件的约束句柄。 一旦锚点为绿色,您可以释放鼠标以完成约束创建。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/80de7244527f710a6d07f43a159dab76.gif"></p>    <p>重要提示:UI Builder会自动启动“自动连接”模式。 由于我们在本节学习手动约束,通过单击操作禁用“自动连接”模式,或确保它已禁用。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/5b69b8b883fe6914945aff4ae4961109.png"></p>    <p>在我们开始之前,确保我们在布局中有一个ImageView和一个TextView。 我们的目标是在ImageView,容器和布局上已经有的TextView控件之间创建约束。</p>    <p>让我们假设我们想要TextView在我们的最终布局中的ImageView下面。 为了实现这一点,我们可以在TextView的顶部锚点和ImageView的底部锚点之间创建一个约束,如图所示。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/7120ad011e9bfa09fb3473142353420f.gif"></p>    <p>删除一个约束</p>    <p>使用布局中显示的icon删除约束按钮删除所选窗口小部件上的 <strong>所有</strong> 约束 。</p>    <p>要删除 <strong>单个</strong> 约束,请单击设置约束的特定锚点。</p>    <p>如果您要删除整个布局中的 <strong>所有约束</strong> ,请使用菜单图标。</p>    <p><img src="https://simg.open-open.com/show/ec8d12439b716b5356afd3fa0ccbd1af.png"></p>    <p>就是这个icon</p>    <ul>     <li style="text-align:center"> <p style="text-align:left">下一步是在ImageView的顶部锚点到布局的顶部之间创建一个约束。</p> <img src="https://simg.open-open.com/show/8fa0476e660b118a3dd259b77bf2d79b.gif"> <p style="text-align:left">注意:在XML代码中,ImageView有错误提示:</p> </li>    </ul>    <p>The view is not constrained vertically: at runtime it will jump to the left unless you add a vertical constraint.</p>    <p>也就是说,手动将ImageView拖动到中央是无效的,必须声明一个垂直居中的约束。</p>    <p>最后,我们还可以使用左右约束将ImageView锚定在布局的中心。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/5a6076eebd86f519e270191cf62567ef.gif"></p>    <p>上述操作导致了如下错误:</p>    <p><img src="https://simg.open-open.com/show/f492446e646789fdaaa11643f08d3d13.png"></p>    <p>原因是没有一个组件的ID是constraintLayout。</p>    <p>将文件中的根View,ConstraintLayout,的id设置为constraintLayout即可。</p>    <p>本节介绍了如何通过拖动连接线来创建窗口小部件之间的约束的基础知识。 此时,您可以通过添加其他元素来浏览视图和UI Builder。 在下一节中,我们将了解检查器。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f441d7b4dd954080281549c4bcba2963.gif"></p>    <p><strong>7. 熟悉 Inspector</strong></p>    <p>在本节中,我们来看看视图检查器。 检查器位于UI构建器的右侧。 除了列出所选窗口小部件的各种属性之外,它还显示视图如何对齐和任何约束。</p>    <p>继续并从布局中删除TextView。</p>    <p>在ImageView的底部锚点和容器底部之间创建约束。</p>    <p>UI构建器应如下所示。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/5a3d23e11b7b380f8d325f0f9522e163.png"></p>    <p>检查器在方块中心显示该ImageView。以下部分描述了各种元素及其用途。</p>    <p>边距:在窗口小部件之外的左,右,顶部和底部是边距。您可以通过单击值并将其设置为不同的值来更改边距。在上面的屏幕截图中,边距设置为16dp。</p>    <p>删除约束:在检查器中单击将窗口小部件连接到容器的线,还可以选择删除约束。注意,删除约束也可以通过点击现有约束句柄来完成。</p>    <p>定位窗口小部件:当窗口小部件上至少有两个相对的连接(例如顶部和底部,或左右)时,您可以看到一个滑块,可以调整窗口小部件沿着轴。这也称为水平或垂直偏置。您可以调整水平和垂直偏置并更改方向以查看偏置是否保持不变。或者,这也可以通过将小部件移动到期望的位置来实现。</p>    <p>继续,将垂直偏压改为75%,将水平偏压改为75%。下面的图片可以作为指南。</p>    <p><img src="https://simg.open-open.com/show/7fe4262bb803dc98d9f5e7ee77e93afd.gif"></p>    <p>在安卓Studio 2.2版本上,Properties下方还有一个View all Properties的按钮。可以看到更多属性。</p>    <p><img src="https://simg.open-open.com/show/c39070c124ad667fc058a3ab7e5412c1.png"></p>    <p>控制窗口小部件的内部尺寸:窗口小部件中的内部线条可让您控制尺寸。 您可以单击特定行以查看它的操作。</p>    <p>这是“检查器”窗格中窗口小部件的放大视图。 单击检查器窗格小部件的内部线将循环选择下面提到的选项。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/92dd85e2b5f2edf62e7b025d827ee654.png"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f358354549e4787de3b09c1e2c35605c.png"></p>    <p>Fixed: 此选项允许您指定窗口小部件的宽度/高度。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ddfbc15b31278f49ebe8aec63a1dccc9.png"></p>    <p>AnySize: 这个选项让部件占据所有可用的空间以满足该约束。换而言之,这有点像match 约束。但是这与占据父View所有的空间的match_parent有所不同。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/2d18a18af99398402c73588529b9147b.png"></p>    <p>Wrap Content: 此选项仅扩展为用所包含的元素(如文本或drawable)填充窗口小部件。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b700eadf9c7f95c9e1b594081d824ad6.png"></p>    <p>AnySize独立于容器。 如果ImageView被约束到一个按钮,AnySize只会展开它,以适应按钮。(图文搭配阅读可有深刻体会)</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/fa156aded563aae520dc27916207c34d.png"></p>    <p>Figure A:在'AnySize'应用于其宽度 <strong>之前</strong> 显示ImageView。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/63ac84507f70cc78159ffffe3f8f5a3c.png"></p>    <p>Figure B: 在'AnySize'应用于其宽度 <strong>之后</strong> 显示ImageView。</p>    <p>要查看和编辑给定窗口小部件的所有其他属性,请单击属性窗格右上角的icon,上述已经讲过这些。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f5698f2954e9d4a266ce11919015ea68.png"></p>    <p>在本节中,我们探讨了检查器。 检查器的目标是让您在不离开UI构建器的情况下编辑所有属性和约束。</p>    <p>8.使用自动连接创建约束</p>    <p>自动连接,顾名思义,自动创建小部件之间的连接。 理解Autoconnect功能尝试创建到相邻小部件的连接非常重要。</p>    <p>在开始使用本节之前,请确保:</p>    <ul>     <li> <p>从“项目”窗格中打开res / layout / activity_main_autoconnect.xml。 确保选择“设计”选项卡。</p> </li>     <li> <p>自动连接已启用</p> </li>    </ul>    <p style="text-align:center"><img src="https://simg.open-open.com/show/81d731bce53de5346a0d85f288e6e684.png"></p>    <p>接下来,我们选择ImageView,并通过拖动它在布局中居中,直到指南显示。 在它居中后几秒钟,自动连接开始,并创建与容器的顶部,左侧,底部和右侧的约束,如下面的动画所示。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b29cca1afcd21fe0a2b4911802538f8e.gif"></p>    <p>这里我们在布局上有一个ImageView,我们看到Autoconnect如何创建约束。</p>    <p><img src="https://simg.open-open.com/show/388efa9d3df35f357653c53edf7a29b3.gif"></p>    <p>以下是本节下一部分的步骤。为了指导,上面的动画显示了下面使用的步骤:</p>    <ol>     <li>对齐要放置在顶部的ImageView,并使用检查器(AnySize)确保它展开以填充父级的宽度。</li>     <li>在布局的右下角放置两个按钮。使用检查器窗格将最右侧按钮的文本属性更改为@ string / upload,将其左侧的文本属性更改为@ string / discard。</li>     <li>从调色板中拖动TextView和纯文本,并将它们放置在布局上。<br> 将TextView和纯文本字段调整为相差48dp。几秒钟后,Autoconnect将为窗口小部件创建约束。</li>     <li>同样选择上传按钮,并将其放在靠近我们的右边距,我们让Autoconnect做剩下的事情。</li>     <li>最后,将discard按钮32dp远离upload按钮。</li>    </ol>    <p>作为练习,也移动TextView 48dp下面的ImageView。要做到这一点,选择TextView并移动,直到它的48dp下面的ImageView。</p>    <p>重要的是要理解Autoconnect仅为当前移动的窗口小部件创建约束。</p>    <p>自动连接通过连接到最近的小部件来帮助您,这在许多情况下是有帮助的。有些情况下,Autoconnect不能实现所需的行为,开发人员应该使用手动约束或推理来构建他们的ConstraintLayout。推论将在代码实验室的下一步中讨论。</p>    <p><strong>9.使用Inference创建约束</strong></p>    <p>Inference引擎通过在布局中添加的元素之间创建约束来帮助开发人员。 Inference创建的约束取决于添加到布局的元素的类型及其大小。</p>    <p>推理和自动连接有什么区别?</p>    <p>推理引擎在布局中的所有元素之间创建约束,而Autoconnect在相邻元素之间创建约束。</p>    <p>自动连接的目的是创建约束来布置正在操作的窗口小部件,即其他窗口小部件不会被约束到您正在移动的窗口小部件,但是您移动的窗口小部件将被限制到其他窗口小部件。 这是一个重要的区别,因为它意味着自动连接不会修改您的当前约束。</p>    <p><strong>setup</strong></p>    <p>对于这一步,我们从layout/activity_main_inference.xml布局开始。 在设计视图中打开布局文件。 默认情况下,此文件中的布局定义以下内容:</p>    <ul>     <li>@drawable/singapore和@drawable/ic_star的ImageViews。 ic_star图像已经被约束为具有81%的垂直偏差。 您可以通过选择包含ic_star的ImageView的垂直偏置,并检查前面讨论的检查器。</li>     <li>大ImageView的底部锚点(@drawable/singapore)被约束到ic_star ImageView的底部锚点,边距为16dp。</li>     <li>除了ImageView之外,还有TextViews for Camera,Settings和ImageView的字幕。</li>    </ul>    <p>你会学到什么</p>    <ul>     <li>使用菜单上的操作水平和垂直扩展视图。</li>     <li>使用inference按钮帮助使用inference创建约束。</li>    </ul>    <p>了解UI Builder图标操作</p>    <p>由于我们将使用一些这些选项,来看看UI Builder上可用的操作。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/a7199fc73ff89c4ccf4c90ed89e80d77.png"></p>    <p>删除所有约束</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ee2e68dc91ded1977e549ad664edbe3d.png"></p>    <p>使用inference创建约束,inference引擎尝试基于各种因素(例如窗口小部件的位置及其大小)找到并创建最佳连接。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/55aa2b97c6308323db1b2e3c1bb99315.png"></p>    <p>水平扩展窗口小部件以满足约束。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/5feecee6065f30fe4fb45d56b73ad884.png"></p>    <p>垂直扩展窗口小部件以满足约束。</p>    <p>添加占用可用空间的TextView</p>    <p>我们的目标是为图像的描述添加一个TextView。 我们已经有一个跨越多行的@string/singapore_description。</p>    <ul>     <li>首先,从调色板中拖动一个TextView,并将其放在设置文本视图下面。</li>     <li>使用操作水平扩展视图以匹配准则。</li>     <li>使用操作垂直扩展以填充可用的垂直空间。 <p><img src="https://simg.open-open.com/show/1ba83163aca321ae0a6e356ed7f61c28.gif"></p> </li>    </ul>    <p>使用 Inference操作</p>    <p>既然你在布局中有TextView,你就可以看到操作中看到Inference。</p>    <p>单击推断constraints 操作以使用推理创建约束。</p>    <p>Inference引擎在布局中的所有视图之间创建约束。 您的最终布局应如下所示:</p>    <p><img src="https://simg.open-open.com/show/456b3db73b89923eac91626fd115ef4f.png"></p>    <p>创建约束后,您可以通过单击UI Builder左上角的按钮来修改“要渲染的虚拟设备”。 选择其他设备(如Nexus 6P或Nexus 9),以查看布局是否正确呈现。</p>    <p>您现在已经看到了使用约束系统的全部范围:使用Inference引擎创建手动约束,使用自动连接的约束和约束。</p>    <p>自动连接和推理帮助您通过布局引擎找出如何为您的UI的各种元素创建约束。 然后,您可以自由地进一步修改由自动连接或推理引擎创建的约束。</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/7cd35953c422</p>    <p> </p>