|
分组框(Group Box)是围绕在一组相关控件周围的带标签的矩形边框。它提供了一种通过视觉展示控件关系
的方法。如下图所示:

本文将通过以下几步来实现:
一、继承SkinnableContainer,创建组件类GroupBox。
二、声明外观部件titleDisplay用来显示组合框的标题。
三、增加title属性。
四、覆盖partAdded方法,使标题字符串能够作用于外观部件titleDisplay。
五、创建它的默认外观(皮肤)GroupBoxSkin。
六、为GroupBox增加必要样式。
---------------
一、继承SkinnableContainer,创建组件类GroupBox。
public class GroupBox extends SkinnableContainer{ public function GroupBox() { super(); }}
二、声明外观部件titleDisplay用来显示组合框的标题。
[SkinPart(required="false")]public var titleDisplay:TextBase;
三、增加title属性。
private var _title:String = "";[Bindable]public function get title():String { return _title;}public function set title(value:String):void { _title = value; if (titleDisplay) titleDisplay.text = title;}
四、覆盖partAdded方法,使标题字符串能够作用于外观部件titleDisplay。
override protected function partAdded(partName:String, instance:Object):void{ super.partAdded(partName, instance); if (instance == titleDisplay) { titleDisplay.text = title; }}
至此,GroupBox组件类基本创建完成,但是还不能显示。下面来创建它的默认外观(皮肤)GroupBoxSkin。
五、创建它的默认外观(皮肤)GroupBoxSkin。
第一步,创建组合框的边框。
<!-- 边框 --> <s:Rect id="border" left="0" right="0" top="10" bottom="0" radiusX="4" radiusY="4" > <s:stroke> <s:SolidColorStroke id="borderStroke" weight="1"/> </s:stroke> </s:Rect>
第二步,创建外观部件titleDisplay。
<!-- 标题 --> <s:Label id="titleDisplay" maxDisplayedLines="1" left="9" top="0" minHeight="20" verticalAlign="middle" textAlign="start"/>
第三步,创建外观部件contentGroup,用于包含组合框的内容。
<!-- 内容区域 --> <s:Group id="contentGroup" left="5" right="5" top="21" bottom="5"> <s:layout> <s:VerticalLayout/> </s:layout> </s:Group>
注意,此时边框是一个闭合的矩形。

图2
从上图,可以看出现在组合框的标题文字与边框是重叠的,显然这不符合我们的要求。
为了解决这个问题,下面要为边框创建一个遮罩。
<!-- 边框遮罩 --> <s:Group id="borderGroupMask" left="0" right="0" top="0" bottom="0"> <s:Rect left="0" width="7" top="0" bottom="0"> <s:fill> <s:SolidColor color="#ff0000" alpha="1"/> </s:fill> </s:Rect> <s:Rect left="7" width="{titleDisplay.width+4}" top="30" bottom="0"> <s:fill> <s:SolidColor color="#ff0000" alpha="1"/> </s:fill> </s:Rect> <s:Rect left="{titleDisplay.width+11}" width="100%" top="0" bottom="0"> <s:fill> <s:SolidColor color="#ff0000" alpha="1"/> </s:fill> </s:Rect> </s:Group>
为<s:Rect id="border"/>增加属性:mask="{borderGroupMask}"。
六、为GroupBox增加必要样式。
第一步,在GroupBox类中增加以下样式声明,它们用来指定边框的颜色和圆角。
增加borderColor样式。
[Style(name="borderColor", type="uint", format="Color", inherit="no", theme="spark")] [Style(name="cornerRadius", type="Number", format="Length", inherit="no", theme="spark")]第二步,在GroupBoxSkin中覆盖updateDisplayList,把样式应用于外观。
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { var cr:Number = getStyle("cornerRadius"); if (cornerRadius != cr) { cornerRadius = cr; // 取变量 border.topLeftRadiusX = cornerRadius; border.topRightRadiusX = cornerRadius; border.bottomLeftRadiusX = cornerRadius; border.bottomRightRadiusX = cornerRadius; } borderStroke.color = getStyle("borderColor"); borderStroke.alpha = getStyle("borderAlpha"); // super.updateDisplayList(unscaledWidth, unscaledHeight); }
至此所有工作完成。效果如下:

图3
完整的文件如下:
1 GroupBox.as
package jx.components{import spark.components.SkinnableContainer;import spark.components.supportClasses.TextBase;/** * The alpha of the border for this component. * * @default 0.5 * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */[Style(name="borderAlpha", type="Number", inherit="no", theme="spark")]/** * The color of the border for this component. * * @default 0 * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */[Style(name="borderColor", type="uint", format="Color", inherit="no", theme="spark")]/** * The radius of the corners for this component. * * @default 5 * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */[Style(name="cornerRadius", type="Number", format="Length", inherit="no", theme="spark")]public class GroupBox extends SkinnableContainer{public function GroupBox(){super();}//----------------------------------// titleField//---------------------------------- [SkinPart(required="false")]/** * 定义容器中标题文本的外观的外观部件。 * * @see jx.skins.GroupBoxSkin * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */public var titleDisplay:TextBase;//----------------------------------// title//----------------------------------/** * @private */private var _title:String = "";/** * @private */private var titleChanged:Boolean;[Bindable]/** * 标题或者说明。 * @default "" * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */public function get title():String {return _title;}/** * @private */public function set title(value:String):void {_title = value;if (titleDisplay)titleDisplay.text = title;}override protected function partAdded(partName:String, instance:Object):void{super.partAdded(partName, instance);if (instance == titleDisplay){titleDisplay.text = title;}}}}
2 GroupBoxSkin.mxml
<?xml version="1.0" encoding="utf-8"?><s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled="0.5"><fx:Metadata>[HostComponent("jx.components.GroupBox")]</fx:Metadata> <fx:Script fb:purpose="styling">static private const exclusions:Array = ["titleDisplay", "contentGroup"];/** * @private */ override public function get colorizeExclusions():Array {return exclusions;}/** * @private */override protected function initializationComplete():void{useChromeColor = true;super.initializationComplete();}private var cornerRadius:Number;/** * @private */override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{var cr:Number = getStyle("cornerRadius");if (cornerRadius != cr){cornerRadius = cr;// 取变量border.topLeftRadiusX = cornerRadius;border.topRightRadiusX = cornerRadius;border.bottomLeftRadiusX = cornerRadius;border.bottomRightRadiusX = cornerRadius;}borderStroke.color = getStyle("borderColor");borderStroke.alpha = getStyle("borderAlpha");//super.updateDisplayList(unscaledWidth, unscaledHeight);}</fx:Script><s:states><s:State name="normal" /><s:State name="disabled" /></s:states><!-- 边框遮罩 --><s:Group id="borderGroupMask" left="0" right="0" top="0" bottom="0"><s:Rect left="0" width="7" top="0" bottom="0"><s:fill><s:SolidColor color="#ff0000" alpha="1"/></s:fill></s:Rect><s:Rect left="7" width="{titleDisplay.width+4}" top="30" bottom="0"><s:fill><s:SolidColor color="#ff0000" alpha="1"/></s:fill></s:Rect><s:Rect left="{titleDisplay.width+11}" width="100%" top="0" bottom="0"><s:fill><s:SolidColor color="#ff0000" alpha="1"/></s:fill></s:Rect></s:Group><!-- 边框 --><s:Rect id="border" left="0" right="0" top="10" bottom="0" radiusX="4" radiusY="4"mask="{borderGroupMask}"><!--mask="{borderGroupMask}"--><s:stroke><s:SolidColorStroke id="borderStroke" weight="1"/></s:stroke></s:Rect><!-- 标题 --><s:Label id="titleDisplay" maxDisplayedLines="1" left="9" top="0" minHeight="20" verticalAlign="middle" textAlign="start"/><!-- 内容区域 --><s:Group id="contentGroup" left="5" right="5" top="21" bottom="5"><s:layout><s:VerticalLayout/></s:layout></s:Group> </s:SparkSkin>
3 GroupBoxExam.mxml 实例文件
<?xml version="1.0" encoding="utf-8"?><s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:components="jx.components.*"><s:layout><s:BasicLayout/></s:layout><fx:Declarations></fx:Declarations><components:GroupBox skinClass="jx.skins.GroupBoxSkin" title="用户配置文件" cornerRadius="5"><components:layout><s:HorizontalLayout/></components:layout><s:Button/><s:Button/><s:Button/></components:GroupBox></s:Application>
4 css
可以通过css为GroupBox指定样式的默认值。
@namespace components "jx.components.*";components|GroupBox {skinClass: ClassReference("jx.skins.GroupBoxSkin");cornerRadius: 5;borderColor: #104778;borderWeight: 1;dropShadowVisible: false;}5 代码方式指定组件的默认CSS样式
private static const classConstructed:Boolean = classConstruct();// 指定默认样式private static function classConstruct():Boolean {var styleManager:IStyleManager2 = FlexGlobals.topLevelApplication.styleManager;if (!styleManager.getStyleDeclaration("jx.components.GroupBox")) {var css:CSSStyleDeclaration = new CSSStyleDeclaration(null, styleManager);css.defaultFactory = function():void {this.skinClass = GroupBoxSkin;this.borderAlpha = 1;this.borderColor = 0;// 黑//this.borderColor = 0xD3D3D3;// 灰//this.borderColor = 0x104778;// 蓝this.cornerRadius = 5;//this.dropShadowVisible = true;//this.borderWeight = 1;}styleManager.setStyleDeclaration("jx.components.GroupBox", css, true);}return true;}
完整的项目请下载附件GroupBoxExam.zip。 |
|