在Flex 2提供的众多新特性中,其中之一就是constraints-based(基于约束的)布局。如果你以前没有机会研究约束(constraints)的使用,我建议你在这种方法上花一些时间。一开始我很怀疑,但是自从用了之后就真正喜欢上了这个轻量级的布局(相比之下,为了得到复杂的布局,flow-based布局方式经常让你陷入box的深层嵌套中)。constraints-based布局的核心是一系列的属性,让你可以定义控件和容器的布置和锚点。
澄清一点:flow-based布局和constraints-based布局并不是互不相容。使用Flex Builder的设计试图,通过将这二种布局结合让他们发挥各自的优势可以加快开发。
我对这些约束(constraints)属性很是好奇,所以有一天我就在语言参考中查找它们。我发现的是他们并不都是属性!一些我曾经用来内联(inline)的约束(constraints)实际上是样式(styles)。这就是说我可以扩展他们并通过一个外部CSS来控制我的用户界面的外观。以下面的代码和屏幕截图作为起点吧。
<mx:Application layout="absolute" xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel
x="10"
y="10"
width="274"
height="148"
layout="absolute"
title="Login">
<mx:Label x="10" y="12" text="Username:" />
<mx:TextInput x="85" y="10" />
<mx:Label x="10" y="42" text="Password:" />
<mx:TextInput x="85" y="40" displayAsPassword="true" />
<mx:ControlBar>
<mx:Button label="Login" />
</mx:ControlBar>
</mx:Panel>
</mx:Application>

在第一部分,当你观察屏幕和代码时,没有什么明显的错误和不足。但是当你仔细一点观察时,你会发现这个用户界面的组合方式的一些缺陷。例如,你可能发现这个登录框总是在应用程序的左上角。但是我们很可能希望通过调整屏幕使它在程序的中间。
这个登录框还被特定地设置成去适应文本框控件的大小。这里并没有文本框控件的宽度信息,所以它们的宽度是默认的150像素。如果我需要向登录框中添加另外一个域并且前面的标签比现有的“username”和“password”标签长,将会发生什么?
这可能会迫使我把文本框向右移动。为了保持对齐,然后我还要重新访问其它的对话框并且让它们向右移动。所有的这些向右移动意味着这个面板要更宽。如果面板中的内容可以在容器的边界范围内自动排列,这会不会变得容易些?
约束(constraints)使我很轻松地解决了这些类型的问题。它们还让我通过Flex Builder的设计试图全部都这样做了(使用约束(constraints))。让我们重新看一些添加了约束(constraints)的代码和屏幕截图。
<mx:Application layout="absolute" xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel
width="275"
height="150"
horizontalCenter="0"
verticalCenter="0"
layout="absolute"
title="Login">
<mx:Label left="10" top="12" text="Username:" />
<mx:TextInput left="85" right="10" top="10" />
<mx:Label left="10" top="42" text="Password:" />
<mx:TextInput left="85" right="10" top="40" displayAsPassword="true" />
<mx:ControlBar>
<mx:Button label="Login" />
</mx:ControlBar>
</mx:Panel>
</mx:Application>

现在不管屏幕如何调整,对话框将会一直在程序的中央。另外,不管面板本身大小如何,username和password标签和文本框控件会一直在它们和面板的相对位置上。作为一个附加的效果,我还可以对面板的宽和高的数值进行取整处理(以前是274*148,现在是275*150)。由于这些控件现在可以适当自己调整大小,所以做一些细微的变化变得很容易。
注意所有的X和Y属性现在都没了,因为用户界面的布局现在都是相对于应用程序其他部分的。
然而还有一个关于用户界面的问题在困扰着我,那就是控制栏(ControlBar)中左对齐(默认方式)的“Login”按钮。大部分操作系统将控制按钮排列在对话框的右下方。这很容易更改,对吗?ControlBar默认遵循Hbox的布局。我们可以对它使用约束(constraints),这种布局为我们工作得很好,就像像刚才,避免了讨厌的对齐工作。
幸运的是,ControlBar容器有一个“horizontalAlign”样式,我可以把这个样式内联,写在标签左边,或者我可以把它放到源代码中任何一个样式块中。大多数情况下我们把样式写到一个样式块中,但是接下来我们将更进一步。我们不喜欢把所有这些风格嵌入到应用程序本身中,所以我们会将它们写到一个外部CSS文件中。现在我们所做的所有更改都会集中在这一个文件中。
但是那些约束(constraints)怎么办?我没有提到过他们也都是样式么?他们也是样式,也可以被提取到同样的CSS中。让我们再来看一下这个应用程序的源代码和屏幕截图。
<mx:Application layout="absolute" xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Style source="constraints3.css" />
<mx:Panel
width="275"
height="150"
layout="absolute"
title="Login">
<mx:Label text="Username:" styleName="userlabel" />
<mx:TextInput styleName="userinput" />
<mx:Label text="Password:" styleName="passlabel" />
<mx:TextInput displayAsPassword="true" styleName="passinput" />
<mx:ControlBar>
<mx:Button label="Login" />
</mx:ControlBar>
</mx:Panel>
</mx:Application>

这个屏幕截图和前面的那个几乎一样,除了“Login”按钮现在对齐到了右边—吆吼!代码只改变了很少,而且改变方式很优雅。现在在适当的地方用样式名取代了原来的约束(constraints)。所有那些讨厌的直接绑定在特定控件上的约束(constraints)现在消失了。实际上它们仍然在那里并且明显看到它们仍然在应用,但是它们现在都在外部的CSS文件中。那个CSS文件才是魔法真正上演的地方,让我们凑近看一下。
ControlBar {
horizontal-align: right;
}
Label {
left: 10;
}
Panel {
horizontal-center: 0;
vertical-center: 0;
}
TextInput {
left: 85;
right: 10;
}
.userlabel {
top: 12;
}
.userinput {
top: 10;
}
.passlabel {
top: 42;
}
.passinput {
top: 40;
}
首先你会发现我在适合对那些控件在块中定义样式的地方用了CSS选择器(selectors)。当你看到TextInput块时,你会发现我没有定义字体和颜色,而是定义了left和right 约束(constraints),因为我希望我的所有的文本框控件都纵向排列,并且保持同样的宽度(相对于容器的边界),定义块级风格就很有意义。文本框和容器顶部关系的约束(constraints)的控制被放在在一个CSS 类别声明中。
所有这些中最好的部分是CSS的层叠特性。TextInput 块中的“left”和“right” 约束(constraints)同样会被被用来定义“top”的类别声明所继承。虽然我们刚才只是看了TextInput,但是对于Label来说这些也一样。这些特性通过在MXML中向控件添加“styleName”属性来实现。
CSS 选择器(selector)和类别声明也可以包含字体,颜色和其他的样式信息。
对约束(constraints)使用这种样式化方式向我提供了一些印象非常深刻的性能。让我们假设一下因为一些原因,不管什么样的原因,我们选择让面板在应用程序的左上方。我可以打开CSS,把"vertical-center" 和"horizontal-center"替换为"left" 和 "top"值,然后就完成了。一个更好的例子可能是:假设我们想要重新排列Label和TextInput控件的顺序。
简单修改一下CSS我就能完全改变控件的排列顺序。当我希望“Password”出现在“Username”前面时,它会像纵向排列一样简单,我还可以把Label控件排列在TextInput空间的右边。不用去搜寻修改内联的属性,只是简单的CSS更改。在Flex Builder设计视图中通过双击修改标签来反映它们新的位置,并且其余的控件会像你想象的一样布局!!
本文介绍了Flex2中基于约束的布局方法,展示了如何利用约束属性简化界面布局调整,并通过外部CSS文件集中管理样式。
3万+

被折叠的 条评论
为什么被折叠?



