<mx:Image source="assets/images/main.jpg" width="500" height="500" maintainAspectRatio="false" />
<s:Image source="assets/images/main.jpg" width="500" height="500" scaleMode="stretch" />
flex填充:
<s:Group includeIn="login" top="0" bottom="0" left="0" right="0">
<s:Rect width="100%" height="100%">
<s:fill>
<s:BitmapFill source="@Embed('assets/images/main.jpg')"/>
</s:fill>
</s:Rect>
</s:Group>
这里如果把embed取消掉,就不会填充任何东西,不知道什么原因?
<s:Group top="0" bottom="0" left="0" right="0">
<s:Rect width="100%" height="100%">
<s:stroke>
<s:SolidColorStroke color="0xbc276a" weight="2"/>
</s:stroke>
<s:fill>
<s:RadialGradient>
<s:entries>
<s:GradientEntry color="0xECEC21" ratio="0.66" alpha="0.5"/>
</s:entries>
</s:RadialGradient>
</s:fill>
</s:Rect>
</s:Group>
stroke表示边框
fill就是填充色了
GradientEntry中的ratio不太明白啥意思
下面是一个弹出框:
本来可以不添加group来填充颜色的,由于我重写了bordercontainer的皮肤,导致这里再设置bgcolor不起作用,还不知道什么原因?
<?xml version="1.0" encoding="utf-8"?> <s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="init()" backgroundColor="{labelBackColor}" backgroundAlpha="0.9" borderAlpha="0" cornerRadius="5" mouseDownOutside="removeHandler()" mouseWheelOutside="removeHandler()" width="160" height="80"> <s:states> <s:State name="messageAlert"/> </s:states> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <fx:Script> <![CDATA[ import cn.dnr.Constants; import mx.managers.PopUpManager; [Bindable] /***显示提示消息*/ public var label:String ; [Bindable] public var labelColor:uint = 0x000000; [Bindable] public var labelFontSize:Number = 14; [Bindable] public var labelBackColor:uint = 0x841553; private function init():void { TimerDelay(); } public function TimerDelay():void { currentState = "messageAlert"; var myTimer:Timer = new Timer(Constants.ALERTTIME); myTimer.addEventListener("timer", timerHandler); myTimer.start(); } public function timerHandler(event:TimerEvent):void { removeHandler(); } protected function removeHandler():void { PopUpManager.removePopUp(this); } ]]> </fx:Script> <!--提示对话窗口--> <s:Group top="0" bottom="0" left="0" right="0"> <s:Rect width="100%" height="100%"> <s:stroke> <s:SolidColorStroke color="0xbc276a" weight="2"/> </s:stroke> <s:fill> <s:RadialGradient> <s:entries> <s:GradientEntry color="0xECEC21" ratio="0.66" alpha="0.5"/> </s:entries> </s:RadialGradient> </s:fill> </s:Rect> </s:Group> <s:Group top="10" bottom="10" left="20" right="20"> <s:Rect width="100%" height="100%"> <s:fill> <s:RadialGradient> <s:entries> <s:GradientEntry color="0x0056FF" ratio="0.00" alpha="0.5"/> </s:entries> </s:RadialGradient> </s:fill> </s:Rect> </s:Group> <s:VGroup includeIn="messageAlert" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle"> <s:Label text="{label}" color="{labelColor}" fontSize="{labelFontSize}"/> </s:VGroup> </s:BorderContainer>
有关重写皮肤,皮肤主要作用是来布局对应组件和设置样式,但同样也可以出发事件,这里需要注意到是,如果要扩展原有组件添加的元素的变量名称需要和皮肤中的一样
如:组件中有一个元素:
[SkinPart(required="false")]
public var btnMin:Image;
皮肤中就应该有对应的
<s:Image id="btnMin" toolTip="最小化" source="assets\images\Buttonminimize.png"
width="18" height="18" right="27" top="7"/>
类型也需要相同,而且[SkinPart(required="false")]这句话不能少,原因也不清楚,先用着吧
下面为重写的titleWindow组件,添加了最小化按钮,是项目中用到的,直接帖过来的
组件:
<?xml version="1.0" encoding="utf-8"?> <s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" skinClass="cn.dnr.skins.TitleWindowSkin"> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <s:states> <s:State name="open"/> <s:State name="minimized"/> <s:State name="restore"/> <s:State name="closed"/> </s:states> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.core.FlexGlobals; import mx.events.CloseEvent; import mx.managers.CursorManager; import spark.components.Button; import spark.components.Image; [SkinPart(required="false")] public var btnMin:Image; // [SkinPart(required="false")] // public var btnMax:Image; // [SkinPart(required="false")] // public var btnRestore:Image; [SkinPart(required="false")] public var btnClose:Image; private var theStatus:int=0;//窗口状态,0正常 1最大化 2最小化; public var isReSize:Boolean;//是否允许缩放 private var theMinWidth:Number=200;//窗口最小宽度 private var theMinHeight:Number=200;//窗口最大高度 private var theOldPoint:Point;//改变大小前窗口的x,y坐标 private var theOldWidth:Number;//最大最小化时的宽 private var theOldHeight:Number;//最大最小化时的高 private var mouseMargin:Number=4;//响应范围 //设置光标的位置值 右上:3 右下:6 左下:11 左上8 private var theSide:Number=0; private var SIDE_OTHER:Number=0; private var SIDE_TOP:Number=1; private var SIDE_RIGHT:Number=2; private var SIDE_LEFT:Number=7; private var SIDE_BOTTOM:Number=4; private var preWidth:Number; private var preHeight:Number; private var preX:Number; private var preY:Number; //当前鼠标光标类 public var currentType:Class=null; //鼠标光标图标 [Embed("assets/images/resizeCursorH.gif")] private var CursorH:Class; [Embed("assets/images/resizeCursorTLBR.gif")] private var CursorR:Class; [Embed("assets/images/resizeCursorTRBL.gif")] private var CursorL:Class; [Embed("assets/images/resizeCursorV.gif")] private var CursorV:Class; private var CursorNull:Class=null; protected override function createChildren():void{ super.createChildren(); //监听按钮事件 // btnClose.addEventListener(MouseEvent.CLICK,onCloseClick); btnMin.addEventListener(MouseEvent.CLICK,onMinClick); // btnMax.addEventListener(MouseEvent.CLICK,onMaxClick); // btnRestore.addEventListener(MouseEvent.CLICK,onReClick); //侦听拖拽相关的事件 this.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove); this.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut); this.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown); } private function onCloseClick(event:MouseEvent):void { // btnMax.visible=true; // btnRestore.visible=false; theStatus=0; this.dispatchEvent(new Event("myClose")); } private function onMinClick(event:MouseEvent):void { onSaveRestore(); this.dispatchEvent(new Event("myMin")); // btnMax.visible = false; // btnRestore.visible=true; theStatus=2; } private function onMaxClick(event:MouseEvent):void { onSaveRestore(); this.dispatchEvent(new Event("myMax")); this.isPopUp=false; // btnMax.visible=false; // btnRestore.visible=true; theStatus=1; preWidth = this.width; preHeight = this.height; preX = this.x; preY = this.y; this.width = stage.width; this.height = stage.height-50; this.x=0; this.y=0; } private function onReClick(event:MouseEvent):void { onGetRestore(); this.dispatchEvent(new Event("myRestore")); this.isPopUp=true; // btnMax.visible=true; // btnRestore.visible=false; theStatus=0; this.width = preWidth; this.height = preHeight; this.x=preX; this.y=preY; } private function onMouseUp(event:MouseEvent):void { if(isReSize) { FlexGlobals.topLevelApplication.removeEventListener(MouseEvent.MOUSE_UP,onMouseUp); FlexGlobals.topLevelApplication.removeEventListener(MouseEvent.MOUSE_MOVE,onResize); isReSize=false; } onChangeCursor(CursorNull); } private function onMouseDown(event:MouseEvent):void { if(theSide!=0) { isReSize=true; FlexGlobals.topLevelApplication.addEventListener(MouseEvent.MOUSE_UP,onMouseUp); FlexGlobals.topLevelApplication.addEventListener(MouseEvent.MOUSE_MOVE,onResize); var point:Point=new Point(); point=this.localToContent(point); theOldPoint=point; } } private function onResize(event:MouseEvent):void { if(isReSize) { var xPlus:Number=FlexGlobals.topLevelApplication.mouseX-this.x; var yPlus:Number=FlexGlobals.topLevelApplication.mouseY-this.y; switch(theSide) { case SIDE_RIGHT+SIDE_BOTTOM: this.width=xPlus>theMinWidth?xPlus:theMinWidth; this.height=yPlus>theMinHeight?yPlus:theMinHeight; break; case SIDE_LEFT+SIDE_TOP: this.width=this.width-xPlus>theMinWidth?this.width-xPlus:theMinWidth; this.height=this.height-yPlus>theMinHeight?this.height-yPlus:theMinHeight; this.x=this.width>theMinWidth?FlexGlobals.topLevelApplication.mouseX:this.x; this.y=this.height>theMinHeight?FlexGlobals.topLevelApplication.mouseY:this.y; break; case SIDE_LEFT+SIDE_BOTTOM: this.width=this.width-xPlus>theMinWidth?this.width-xPlus:theMinWidth; this.height=yPlus>theMinHeight?yPlus:theMinHeight; this.x=this.width>theMinWidth?FlexGlobals.topLevelApplication.mouseX:this.x; break; case SIDE_RIGHT+SIDE_TOP: this.width=xPlus>theMinWidth?xPlus:theMinWidth; this.height=this.height-yPlus>theMinHeight?this.height-yPlus:theMinHeight; this.y=this.height>theMinHeight?FlexGlobals.topLevelApplication.mouseY:this.y; break; case SIDE_RIGHT: this.width=xPlus>theMinWidth?xPlus:theMinWidth; break; case SIDE_LEFT: this.width=this.width-xPlus>theMinWidth?this.width-xPlus:theMinWidth; this.x=this.width>theMinWidth?FlexGlobals.topLevelApplication.mouseX:this.x; break; case SIDE_BOTTOM: this.height=yPlus>theMinHeight?yPlus:theMinHeight; break; case SIDE_TOP: this.height=this.height-yPlus>theMinHeight?this.height-yPlus:theMinHeight; this.y=this.height>theMinHeight?FlexGlobals.topLevelApplication.mouseY:this.y; break; } } } private function onMouseOut(event:MouseEvent):void { if(!isReSize&&this.theStatus==0) { theSide=0; onChangeCursor(CursorNull); this.isPopUp=true; } } private function onMouseMove(event:MouseEvent):void { if(!theStatus) { var point:Point=new Point(); point=this.localToGlobal(point); var xPosition:Number=FlexGlobals.topLevelApplication.mouseX; var yPosition:Number=FlexGlobals.topLevelApplication.mouseY; if(xPosition>=(point.x+this.width-mouseMargin)&&yPosition>=(point.y+this.height-mouseMargin)) {//右下 onChangeCursor(CursorR,-9,-9); theSide=SIDE_RIGHT+SIDE_BOTTOM; this.isPopUp=false; }else if(xPosition<=(point.x+mouseMargin)&&yPosition<=(point.y+mouseMargin)) {//左上 onChangeCursor(CursorR,-9,-9); theSide=SIDE_LEFT+SIDE_TOP; this.isPopUp=false; }else if(xPosition<=(point.x+mouseMargin)&&yPosition>=(point.y+this.height-mouseMargin)) {//左下 onChangeCursor(CursorL,-9,-9); theSide=SIDE_BOTTOM+SIDE_LEFT; this.isPopUp=false; }else if(xPosition>=(point.x+this.width-mouseMargin)&&yPosition<=(point.y+mouseMargin)) {//右上 onChangeCursor(CursorL,-9,-9); theSide=SIDE_RIGHT+SIDE_TOP; this.isPopUp=false; }else if(xPosition>(point.x+this.width-mouseMargin)) {//右 onChangeCursor(CursorH,-9,-9); theSide=SIDE_RIGHT; this.isPopUp=false; }else if(xPosition<(point.x+mouseMargin)) {//左 onChangeCursor(CursorH,-9,-9); theSide=SIDE_LEFT; this.isPopUp=false; }else if(yPosition<(point.y+mouseMargin)) {//上 onChangeCursor(CursorV,-9,-9); theSide=SIDE_TOP; this.isPopUp=false; } else if(yPosition>(point.y+this.height-mouseMargin)) {//下 onChangeCursor(CursorV,-9,-9); theSide=SIDE_BOTTOM; this.isPopUp=false; } else { onChangeCursor(CursorNull); if(!isReSize&&theStatus==0) { theSide=0; this.isPopUp=true; } } event.updateAfterEvent(); } } private function onChangeCursor(type:Class,xOffset:Number=0,yOffset:Number=0):void { if(currentType!=type) { currentType=type; CursorManager.removeCursor(CursorManager.currentCursorID); if(type!=null) { CursorManager.setCursor(type,2,xOffset,yOffset); } } } private function onSaveRestore():void { var point:Point=new Point(); theOldPoint=this.localToGlobal(point); theOldWidth=this.width; theOldHeight=this.height; } private function onGetRestore():void { this.x=theOldPoint.x; this.y=theOldPoint.y this.width=theOldWidth; this.height=theOldHeight; } ]]> </fx:Script> </s:TitleWindow>
皮肤:
<?xml version="1.0" encoding="utf-8"?> <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:fb="http://ns.adobe.com/flashbuilder/2009" blendMode="normal" mouseEnabled="false" minWidth="176" minHeight="76" alpha.disabled="0.5" alpha.disabledWithControlBar="0.5"> <fx:Metadata> <![CDATA[ /** * @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.TitleWindow")] ]]> </fx:Metadata> <fx:Script fb:purpose="styling"> <![CDATA[ import mx.core.FlexVersion; /* Define the skin elements that should not be colorized. For panel, border and title background are skinned, but the content area, background, border, and title text are not. */ static private const exclusions:Array = ["background", "titleDisplay", "contentGroup", "border"]; /* exclusions before Flex 4.5 for backwards-compatibility purposes */ static private const exclusions_4_0:Array = ["background", "titleDisplay", "contentGroup"]; /** * @private */ override public function get colorizeExclusions():Array { // Since border is styleable via borderColor, no need to allow chromeColor to affect // the border. This is wrapped in a compatibility flag since this change was added // in Flex 4.5 if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_5) { return exclusions_4_0; } return exclusions; } /** * @private */ override protected function initializationComplete():void { useChromeColor = true; super.initializationComplete(); } /** * @private */ override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { if (getStyle("borderVisible") == true) { border.visible = true; background.left = background.top = background.right = background.bottom = 1; contents.left = contents.top = contents.right = contents.bottom = 1; } else { border.visible = false; background.left = background.top = background.right = background.bottom = 0; contents.left = contents.top = contents.right = contents.bottom = 0; } dropShadow.visible = getStyle("dropShadowVisible"); var cr:Number = getStyle("cornerRadius"); var withControls:Boolean = (currentState == "disabledWithControlBar" || currentState == "normalWithControlBar" || currentState == "inactiveWithControlBar"); if (cornerRadius != cr) { // cornerRadius = cr; dropShadow.tlRadius = cornerRadius; dropShadow.trRadius = cornerRadius; dropShadow.blRadius = withControls ? cornerRadius : 0; dropShadow.brRadius = withControls ? cornerRadius : 0; setPartCornerRadii(topMaskRect, withControls); setPartCornerRadii(border, withControls); setPartCornerRadii(background, withControls); } if (bottomMaskRect) setPartCornerRadii(bottomMaskRect, withControls); borderStroke.color = getStyle("borderColor"); borderStroke.alpha = getStyle("borderAlpha"); backgroundFill.color = getStyle("backgroundColor"); backgroundFill.alpha = getStyle("backgroundAlpha"); super.updateDisplayList(unscaledWidth, unscaledHeight); } /** * @private */ private function setPartCornerRadii(target:Rect, includeBottom:Boolean):void { target.topLeftRadiusX = cornerRadius; target.topRightRadiusX = cornerRadius; target.bottomLeftRadiusX = includeBottom ? cornerRadius : 0; target.bottomRightRadiusX = includeBottom ? cornerRadius : 0; } private var cornerRadius:Number=5; ]]> </fx:Script> <s:states> <s:State name="normal" /> <s:State name="inactive" stateGroups="inactiveGroup" /> <s:State name="disabled" /> <s:State name="normalWithControlBar" stateGroups="withControls" /> <s:State name="inactiveWithControlBar" stateGroups="withControls, inactiveGroup" /> <s:State name="disabledWithControlBar" stateGroups="withControls" /> </s:states> <!--- drop shadow can't be hittable so it stays sibling of other graphics @private--> <s:RectangularDropShadow id="dropShadow" blurX="20" blurY="20" alpha="0.32" alpha.inactiveGroup="0.22" distance="11" distance.inactiveGroup="7" angle="90" color="0x000000" left="0" top="0" right="0" bottom="0"/> <!--- drop shadow can't be hittable so all other graphics go in this group --> <s:Group left="0" right="0" top="0" bottom="0"> <!--- top group mask @private--> <s:Group left="1" top="1" right="1" bottom="1" id="topGroupMask"> <!--- @private--> <s:Rect id="topMaskRect" left="0" top="0" right="0" bottom="0" > <s:fill> <s:SolidColor alpha="0"/> </s:fill> </s:Rect> </s:Group> <!--- bottom group mask @private--> <s:Group left="1" top="1" right="1" bottom="1" id="bottomGroupMask" includeIn="withControls"> <!--- @private--> <s:Rect id="bottomMaskRect" left="0" top="0" right="0" bottom="0"> <s:fill> <s:SolidColor alpha="0"/> </s:fill> </s:Rect> </s:Group> <!--- layer 1: border @private --> <s:Rect id="border" left="0" right="0" top="0" bottom="0" > <s:stroke> <!--- Defines the TitleWindowSkin class's border stroke. The default value is 1. --> <s:SolidColorStroke id="borderStroke" weight="1" /> </s:stroke> </s:Rect> <!-- layer 2: background fill --> <!--- Defines the appearance of the TitleWindowSkin class's background. --> <s:Rect id="background" left="1" top="1" right="1" bottom="1"> <s:fill> <!--- Defines the TitleWindowSkin class's background fill. The default color is 0xFFFFFF. --> <s:SolidColor id="backgroundFill" color="#FFFFFF"/> </s:fill> </s:Rect> <!-- layer 3: contents --> <!--- Contains the vertical stack of title bar content and control bar. --> <s:Group left="1" right="1" top="1" bottom="1" id="contents"> <s:layout> <s:VerticalLayout gap="0" horizontalAlign="justify" /> </s:layout> <!--- @private --> <s:Group id="topGroup" mask="{topGroupMask}"> <!--- layer 0: title bar fill @private --> <s:Rect id="tbFill" left="0" right="0" top="0" bottom="1" > <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0x3399CC" color.inactiveGroup="0x99aaaa"/> <s:GradientEntry color="0x0066aa" color.inactiveGroup="0x808080"/> <!--- <s:GradientEntry color="0xD2D2D2" color.inactiveGroup="0xEAEAEA"/> <s:GradientEntry color="0x9A9A9A" color.inactiveGroup="0xCECECE"/> --> </s:LinearGradient> </s:fill> </s:Rect> <!--- layer 1: title bar highlight @private --> <s:Rect id="tbHilite" left="0" right="0" top="0" bottom="0" > <s:stroke> <s:LinearGradientStroke rotation="90" weight="1"> <s:GradientEntry color="0xE6E6E6" /> <s:GradientEntry color="0xFFFFFF" alpha="0.22"/> </s:LinearGradientStroke> </s:stroke> <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0xFFFFFF" alpha="0.15" /> <s:GradientEntry color="0xFFFFFF" alpha="0.15" ratio="0.44"/> <s:GradientEntry color="0xFFFFFF" alpha="0" ratio="0.4401"/> </s:LinearGradient> </s:fill> </s:Rect> <!--- layer 2: title bar divider @private --> <s:Rect id="tbDiv" left="0" right="0" height="1" bottom="0" > <s:fill> <s:SolidColor color="0x000000" alpha="0.75" /> </s:fill> </s:Rect> <!-- layer 3: text --> <!--- @copy spark.components.Panel#titleDisplay --> <s:Label id="titleDisplay" maxDisplayedLines="1" left="9" right="36" top="1" bottom="0" minHeight="30" verticalAlign="middle" fontWeight="bold" /> <!-- layer 4: moveArea --> <!--- @copy spark.components.TitleWindow#moveArea --> <s:Group id="moveArea" left="0" right="0" top="0" bottom="0" /> <!--- @copy spark.components.TitleWindow#closeButton <s:Image id="btnMax" toolTip="最大化" source="assets\images\Buttonmaximize.png" width="18" height="18" right="27" top="7"/> <s:Image id="btnRestore" visible="false" toolTip="还原" source="assets\images\Buttonrestore.png" width="18" height="18" right="27" top="7"/> --> <s:Image id="btnMin" toolTip="最小化" source="assets\images\Buttonminimize.png" width="18" height="18" right="27" top="7"/> <s:Button id="closeButton" skinClass="spark.skins.spark.TitleWindowCloseButtonSkin" width="15" height="15" right="7" top="7" /> </s:Group> <!-- Note: setting the minimum size to 0 here so that changes to the host component's size will not be thwarted by this skin part's minimum size. This is a compromise, more about it here: http://bugs.adobe.com/jira/browse/SDK-21143 --> <!--- @copy spark.components.SkinnableContainer#contentGroup --> <s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0"> </s:Group> <!--- @private --> <s:Group id="bottomGroup" minWidth="0" minHeight="0" includeIn="withControls"> <s:Group left="0" right="0" top="0" bottom="0" mask="{bottomGroupMask}"> <!-- layer 0: control bar divider line --> <s:Rect left="0" right="0" top="0" height="1" alpha="0.22"> <s:fill> <s:SolidColor color="0x000000" /> </s:fill> </s:Rect> <!-- layer 1: control bar highlight --> <s:Rect left="0" right="0" top="1" bottom="0"> <s:stroke> <s:LinearGradientStroke rotation="90" weight="1"> <s:GradientEntry color="0xFFFFFF" /> <s:GradientEntry color="0xD8D8D8" /> </s:LinearGradientStroke> </s:stroke> </s:Rect> <!-- layer 2: control bar fill --> <s:Rect left="1" right="1" top="2" bottom="1"> <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0xEDEDED"/> <s:GradientEntry color="0xCDCDCD"/> </s:LinearGradient> </s:fill> </s:Rect> </s:Group> <!--- @copy spark.components.Panel#controlBarGroup --> <s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0"> <s:layout> <s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="7" paddingBottom="7" gap="10" /> </s:layout> </s:Group> </s:Group> </s:Group> </s:Group> </s:SparkSkin>