Flex 4:有一种简单的方法来扩展Spark按钮吗?

Gre*_*gir 2 apache-flex button extend flex-spark

我通过执行File> New> MXML外观并基于spark.components.button创建了一个有点自定义的Spark按钮.问题是我需要在按钮组件中添加一个额外的文本字段并动态更改该文本...但当然,在Spark按钮上无法识别该属性.

有没有一种简单的方法将此字段添加到我的自定义按钮皮肤及其属性,以便可以解决?如果没有,是否有一种简单的方法来完成我所做的并只是扩展Spark按钮?我似乎无法找到任何显示如何在没有在ActionScript中编写所有内容的示例.

Jon*_*ine 6

我很高兴你问!这比你想象的容易得多,所以不要气馁!一旦掌握了它,ActionScript就非常容易了.

首先,让我们定义我们想要的东西.看完你的问题后,我相信你想用你的按钮:

<local:MyCustomButton label="Hello" label2="World!"/>
Run Code Online (Sandbox Code Playgroud)

那么让我们来看看如何实现这一目标.

现在,我强烈建议使用ActionScript扩展Button,但也可以在mxml中执行:

//MyCustomButton.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx">

</s:Button>
Run Code Online (Sandbox Code Playgroud)

然后,您可以在以下位置添加所需的SkinParts <fx:Script>:

<?xml version="1.0" encoding="utf-8"?>
<s:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx">

    <fx:Script>
        <![CDATA[

            [SkinPart]
            public var secondLabelDisplay:spark.components.Label;


        ]]>
    </fx:Script>


</s:Button>
Run Code Online (Sandbox Code Playgroud)

所以现在当你制作一个皮肤时,你应该包含一些类似原始标签的东西,只是使用不同的ID来反映你的新SkinPart:

可是等等!我们的第二个标签应显示什么文字?好吧,我们需要添加另一个属性,您可以为按钮的每个单独实例设置:

<?xml version="1.0" encoding="utf-8"?>
<s:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx">

    <fx:Script>
        <![CDATA[

            [SkinPart]
            public var secondLabelDisplay:spark.components.Label;


            private var _label2:String;

            public function get label2():String
            {
                return _label2;
            }

            public function set label2(value:String):void
            {
                _label2 = value;
            }


        ]]>
    </fx:Script>


</s:Button>
Run Code Online (Sandbox Code Playgroud)

很酷,所以现在我们可以在使用我们的按钮时设置label2,但此时它不会改变标签的实际文本属性.我们需要将label2连接到secondLabelDisplay.我们这样做是通过在label2更改时调用invalidateProperties然后更改commitProperties中的标签(由于invalidateProperties()调用将调用它):

  <?xml version="1.0" encoding="utf-8"?>
    <s:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
              xmlns:s="library://ns.adobe.com/flex/spark" 
              xmlns:mx="library://ns.adobe.com/flex/mx">

        <fx:Script>
            <![CDATA[

                [SkinPart]
                public var secondLabelDisplay:spark.components.Label;


                private var _label2:String;
                private var label2Changed:Boolean;

                public function get label2():String
                {
                    return _label2;
                }

                public function set label2(value:String):void
                {
                    _label2 = value;
                    label2Changed = true;
                    invalidateProperties();
                }

                override protected function commitProperties():void
                {
                    super.commitProperties();

                    if(label2Changed)
                    {
                        label2Changed = false;
                                            secondLabelDisplay.text = label2;
                    }

                }


            ]]>
        </fx:Script>


    </s:Button>
Run Code Online (Sandbox Code Playgroud)

最后,您会注意到,如果您在label2运行时间后再次更改,标签将显示更改.但是,如果您label2在我们的目标使用中设置初始值,则不会显示更改.Flex团队为这种情况做了一个特殊的方法,partAdded().我不会详细介绍它,因为已有大量有关该主题的文献.

最后,这是我们完成的自定义按钮,等待皮肤使用:

<fx:Script>
    <![CDATA[

        [SkinPart]
        public var secondLabelDisplay:spark.components.Label;


        private var _label2:String;
        private var label2Changed:Boolean;

        public function get label2():String
        {
            return _label2;
        }

        public function set label2(value:String):void
        {
            _label2 = value;
            label2Changed = true;
            invalidateProperties();
        }

        override protected function commitProperties():void
        {
            super.commitProperties();

            if(label2Changed)
            {
                label2Changed = false;
                                    secondLabelDisplay.text = label2;
            }

        }

        override protected function partAdded(partName:String, instance:Object):void
        {
            if(instance == secondLabelDisplay)
            {
                secondLabelDisplay.text = _label2;
            }

        }


    ]]>
</fx:Script>
Run Code Online (Sandbox Code Playgroud)

祝你好运!