【问题标题】:ActionScript: Changing a spark TitleWindow's titlebar colorActionScript:更改火花 TitleWindow 的标题栏颜色
【发布时间】:2011-10-23 01:48:47
【问题描述】:

我有一个简单的疑问。我制作了一个自定义的 ActionScript mxml 组件,它是一个带有文本区域的 spark TitleWindow,如果它在其文本中找到单词“success”,则标题(标题栏)应该显示绿色背景,如果没有,则显示红色。

我的问题是我不知道在哪里访问和修改此属性,我发现的唯一转变是将 TitleWindow 的“chromeColor”绑定到一个布尔值,该布尔值将根据我是否找到或者不是“成功”这个词。这确实将 TitleBar 背景更改为我想要的颜色,但是,它也会更改滚动条颜色,例如,这有点讨厌。我的课的代码如下:

<?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" width="400" 
           title="Output: "
           chromeColor="{success ? ( 0x00ff6b as uint) : ( 0xFF0000 as uint)}"
           close="closeHandler(event)">
<fx:Script>
    <![CDATA[
        import mx.events.CloseEvent;
        import mx.managers.PopUpManager;

        [Bindable]
        public var success:Boolean = false;

        public function setText(text:String):void
        {
            textContainer.text = text;
            if(text.indexOf("SUCCESS")!=-1)
            {
                success=true;
            }
        }

        protected function closeHandler(event:CloseEvent):void
        {
            PopUpManager.removePopUp(this);
        }

    ]]>
</fx:Script>
<s:TextArea id="textContainer" x="0" y="0"  width="100%" height="100%"
            paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10" 
            borderVisible="false" editable="false" fontFamily="Courier New"/>
</s:TitleWindow>

所以,感谢阅读,希望有人知道答案:)

干杯, 佩皮罗

【问题讨论】:

    标签: actionscript-3 apache-flex flex4 custom-controls flex-spark


    【解决方案1】:

    我会通过扩展标准组件和创建自定义皮肤来解决它。

    我的组件版本:

    package
    {
    import flash.events.MouseEvent;
    
    import mx.managers.PopUpManager;
    
    import spark.components.TextArea;
    import spark.components.TitleWindow;
    
    [SkinState("disabledSuccessful")]
    [SkinState("disabledWithControlBarSuccessful")]
    [SkinState("inactiveSuccessful")]
    [SkinState("inactiveWithControlBarSuccessful")]
    [SkinState("normalSuccessful")]
    [SkinState("normalWithControlBarSuccessful")]
    public class SuccessfulTitleWindow extends TitleWindow
    {
        public function SuccessfulTitleWindow()
        {
            title = "Output: ";
        }
    
        [SkinPart(required = "false")]
        public var textContainer:TextArea;
    
        private var success:Boolean;
        private var textChanged:Boolean;
        private var textValue:String;
    
        /**
         * @inheritDoc
         */
        override protected function commitProperties():void
        {
            super.commitProperties();
    
            if (textChanged && textContainer)
            {
                textContainer.text = textValue;
                textChanged = false;
            }
        }
    
        /**
         * @inheritDoc
         */
        override protected function getCurrentSkinState():String
        {
            var skinState:String = super.getCurrentSkinState();
            return success ? skinState + "Successful" : skinState;
        }
    
        /**
         * @inheritDoc
         */
        override protected function partAdded(partName:String, instance:Object):void
        {
            super.partAdded(partName, instance);
            if (instance == textContainer)
            {
                textChanged = true;
                invalidateProperties();
            }
        }
    
        public function setText(text:String):void
        {
            if (text == textValue)
                return;
            success = text && text.indexOf("SUCCESS") != -1;
            invalidateSkinState();
            textValue = text;
            textChanged = true;
            invalidateProperties();
        }
    
        /**
         * @inheritDoc
         */
        override protected function closeButton_clickHandler(event:MouseEvent):void
        {
            super.closeButton_clickHandler(event);
    
            PopUpManager.removePopUp(this);
        }
    }
    }
    

    皮肤(基于标准皮肤):

    <?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="76" minHeight="76" alpha.disabledGroup="0.5" width="400">
        <fx:Metadata>[HostComponent("SuccessfulTitleWindow")]</fx:Metadata>
    
        <fx:Script fb:purpose="styling">
            /* Define the skin elements that should not be colorized. 
            For panel, border and title background are skinned, but the content area and title text are not. */
            static private const exclusions:Array = ["background", "titleDisplay", "contentGroup"];
    
            /**
             * @private
             */  
            override public function get colorizeExclusions():Array {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;
        </fx:Script>
    
        <s:states>
            <s:State name="normal" stateGroups="normalGroup" />
            <s:State name="inactive" stateGroups="inactiveGroup" />
            <s:State name="disabled" stateGroups="disabledGroup" />
            <s:State name="normalWithControlBar" stateGroups="withControls, normalGroup" />
            <s:State name="inactiveWithControlBar" stateGroups="withControls, inactiveGroup" />
            <s:State name="disabledWithControlBar" stateGroups="withControls, disabledGroup" />
            <s:State name="normalSuccessful" stateGroups="successfulGroup, normalGroup" />
            <s:State name="inactiveSuccessful" stateGroups="inactiveGroup,successfulGroup" />
            <s:State name="disabledSuccessful" stateGroups="successfulGroup,disabledGroup" />
            <s:State name="normalWithControlBarSuccessful" stateGroups="withControls,successfulGroup,normalGroup" />
            <s:State name="inactiveWithControlBarSuccessful" stateGroups="withControls, inactiveGroup, successfulGroup" />
            <s:State name="disabledWithControlBarSuccessful" stateGroups="withControls, successfulGroup, disabledGroup" />
        </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:SolidColor color="0xFF0000" color.successfulGroup="0x00ff6b" alpha.inactiveGroup="0.8" />
                        </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: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:TextArea id="textContainer" width="100%" height="100%"
                        paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10" 
                        borderVisible="false" editable="false" fontFamily="Courier New"/>
                </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>
    

    以及要测试的简单应用:

    <?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:local="*">
        <s:VGroup verticalCenter="0" horizontalCenter="0">
            <local:SuccessfulTitleWindow skinClass="SuccessfulTitleWindowSkin" id="window" />
            <s:TextInput change="window.setText(event.currentTarget.text)" />
        </s:VGroup>
    </s:Application>
    

    【讨论】:

      【解决方案2】:

      Flex 4 的方法是通过复制 TitleWindowSkin 的代码来创建自己的自定义皮肤类,并将其更新为绿色背景。然后,您可以通过将 skinClass 属性添加到 TitleWindow 标记或在 CSS 配置中设置 skinClass 来告诉 fex 使用您的自定义皮肤。

      【讨论】:

      • 真的没有更快/更简单的方法吗? :(
      • 嗯......这有那么复杂吗?问题是,在 Flex4 中,特别是 spark 控制器和视图真的很好地分开了......具有所有优点和缺点。您需要做的就是复制原件,然后根据需要调整第 184 到 194 行。我知道 Spark 蒙皮一开始看起来既困难又复杂,但一段时间后你肯定会真正开始喜欢它 ;-)
      【解决方案3】:

      如果使用 FlashBuilder,请创建一个从要覆盖的皮肤类型派生的新 MXML 皮肤(最好使用名为 skins 的包)。然后创建一个新的 ActionScript 类并扩展 MXML 外观。 然后,您将可以完全控制皮肤,并且可以在必要时扩展模板。

      就我而言,我想覆盖 TitleWindow [spark.skins.spark.TitleWindowSkin] 的皮肤(即使在移动设备上)。许多对话框项目(即标题栏)不可换肤,而是硬编码。 tbFill 是 TitleBar 的 ID。我能够调整皮肤代码以将 ID 属性名称分配给标题栏渐变并读取样式值以设置颜色 [在 updateDisplayList 函数中]。 然后使用您的自定义皮肤类的名称作为您正在皮肤的项目的skinClass 属性。

      skinClass="skins.defaultSkin"
      

      总的来说,使用这种方法并不难。这是皮肤类。

      package skins
      {
          
          public class defaultSkin extends dlgTitleWindowSkin 
          {
              public function defaultSkin()
              {
                  super();
                  this.setStyle("backgroundColor","#fff2bd");
                  this.setStyle("tbFill_GradientStart","#ff5f3b");
                  this.setStyle("tbFill_GradientEnd","#ff5f3b ");
              }
          }
      }
      

      在派生的 MXML 皮肤中:

      override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
      {
      ...
                  tbFill_GradientStart.color = getStyle("tbFill_GradientStart");
                  tbFill_GradientEnd.color = getStyle("tbFill_GradientEnd");
                  
                  super.updateDisplayList(unscaledWidth, unscaledHeight);
      }
      ...
          <!--- 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 id="tbFill_GradientStart" color="0xD2D2D2"
                                       color.inactiveGroup="0xEAEAEA"/>
                      <s:GradientEntry id="tbFill_GradientEnd" color="0x9A9A9A"
                                       color.inactiveGroup="0xCECECE"/>
                  </s:LinearGradient>
              </s:fill>
          </s:Rect>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-02
        • 1970-01-01
        • 2011-05-26
        • 2011-03-03
        • 2013-04-20
        • 2016-09-13
        相关资源
        最近更新 更多