首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AS3 3/Flex自定义TextInput组件填充

AS3 3/Flex自定义TextInput组件填充
EN

Stack Overflow用户
提问于 2014-03-22 05:53:37
回答 1查看 1.3K关注 0票数 1

我正在尝试创建一个自定义TextInput组件,该组件的内部有一个标签,标签旁边有实际的输入框。如下图所示(Photoshop切片):

我大部分时间都在工作。但是,当文本到达框的末尾时,它会一直到边框(完全忽略填充),然后当输入更多的字符时,它会将文本的左侧向右推到USERNAME标签(同样,忽略填充)。正如您在这张图片中所看到的(Flex屏幕快照)

除了改变滚动条的皮肤之外,这是我做过的第一个定制组件和皮肤,我已经花了一天的时间来研究它。我知道这可能很容易,但我想不出来。如果有人能告诉我该怎么做的话,我会非常感激的.

我到目前为止的密码是这样的.

com.controls.LabeledTextInput.as:

代码语言:javascript
复制
package com.controls
{
    import flash.events.FocusEvent;
    import spark.components.TextInput;
    import spark.core.IDisplayText;
    import mx.core.FlexGlobals;
    import mx.styles.CSSStyleDeclaration;

    //--------------------------------------
    //  Styles
    //--------------------------------------

    /**
     *  The alpha of the border for this component.
     */
    [Style(name="focusBorderAlpha", type="Number", inherit="no", theme="spark", minValue="0.0", maxValue="1.0")]

    /**
     *  The color of the border for this component.
     */
    [Style(name="focusBorderColor", type="uint", format="Color", inherit="no", theme="spark")]

    /**
     *  Controls the visibility of the border for this component.
     */
    [Style(name="focusBorderVisible", type="Boolean", inherit="no", theme="spark, mobile")]

    /**
     *  Shorthand padding around the textDisplay subcomponent.
     *  This property works like the CSS padding style. Eg.
     *  padding: 2 4 2 4    (top right bottom left)
     *  padding: 2 4 2      (top right/left bottom)
     *  padding: 2 4        (top/bottom right/left)
     *  padding: 2          (top/right/bottom/left)
     */
    [Style(name="padding", type="String", inherit="no", theme="spark")]

    /**
     *  Padding around the labelDisplay subcomponent.
     *  This property works like the CSS padding style. Eg.
     *  padding: 2 4 2 4    (top right bottom left)
     *  padding: 2 4 2      (top right/left bottom)
     *  padding: 2 4        (top/bottom right/left)
     *  padding: 2          (top/right/bottom/left)
     */
    [Style(name="labelPadding", type="String", inherit="no", theme="spark")]

    //--------------------------------------
    //  Skin states
    //--------------------------------------

    /**
     *  Focus State of the TextInput
     */
    [SkinState("focused")]

    public class LabeledTextInput extends TextInput
    {
        [SkinPart(required="false")]

        /**
         *  A skin part that defines the label of the input. 
         */
        public var labelDisplay:IDisplayText;

        /**
         *  Var for storing the label.
         */
        private var _label:String;

        /**
         *  Keeps track of our focus state.
         */
        private var inFocus:Boolean;

        /**
         *  Used for setting default property values.
         */
        private static var classConstructed:Boolean = classConstruct();

        // Set default style values
        private static function classConstruct() : Boolean
        {
            if (!FlexGlobals.topLevelApplication.styleManager.getStyleDeclaration("com.controls.LabeledTextInput"))
            {
                var labeledTextInputStyles:CSSStyleDeclaration = new CSSStyleDeclaration();
                labeledTextInputStyles.defaultFactory = function() : void
                {
                    this.focusBorderAlpha = 1;
                    this.focusBorderColor = 0xE2E2D9;
                    this.focusBorderVisible = true;
                    this.paddingTop = NaN;
                    this.paddingRight = NaN;
                    this.paddingBottom = NaN;
                    this.paddingLeft = NaN;
                    this.padding = null;
                    this.labelPadding = null;
                }
                FlexGlobals.topLevelApplication.styleManager.setStyleDeclaration("com.controls.LabeledTextInput", labeledTextInputStyles, true);
            }
            return true;
        }       

        public function LabeledTextInput()
        {
            super();
        }

        [Bindable]
        public function get label() : String
        {
            return _label;
        }

        public function set label(value:String) : void
        {
            if(_label != value)
            {
                _label = value;
                if(labelDisplay != null)
                {
                    labelDisplay.text = value;
                }
            }
        }

        /* Implement the getCurrentSkinState() method to set the view state of the skin class. */
        override protected function getCurrentSkinState() : String
        {
            return (inFocus == true) ? "focused" : super.getCurrentSkinState();
        } 

        /* Set the label and attach focus even handlers. */ 
        override protected function partAdded(partName:String, instance:Object) : void
        {
            super.partAdded(partName, instance);

            if (instance == labelDisplay)
            {
                labelDisplay.text = label;
            }
            else if(instance == textDisplay)
            {
                textDisplay.addEventListener(FocusEvent.FOCUS_IN, onFocusInHandler);
                textDisplay.addEventListener(FocusEvent.FOCUS_OUT, onFocusOutHandler);
            }
        }

        /* Remove the focus event handlers. */
        override protected function partRemoved(partName:String, instance:Object) : void
        {
            super.partRemoved(partName, instance);

            if(instance == textDisplay)
            {
                textDisplay.removeEventListener(FocusEvent.FOCUS_IN, onFocusInHandler);
                textDisplay.removeEventListener(FocusEvent.FOCUS_OUT, onFocusOutHandler);
            }
        }

        /* Handler for FocusIn Event */
        private function onFocusInHandler(event:FocusEvent) : void
        {
            inFocus = true;
            invalidateSkinState();
        }

        /* Handler for FocusOut */
        private function onFocusOutHandler(event:FocusEvent) : void
        {
            inFocus = false;
            invalidateSkinState();
        }
    }
}

com.controls.skins.LabeledTextInputSkin.mxml:

代码语言:javascript
复制
<?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" 
    alpha.disabledStates="0.5" blendMode="normal">

    <fx:Metadata>
    <![CDATA[ 
        [HostComponent("com.controls.LabeledTextInput")]
    ]]>
    </fx:Metadata> 

    <fx:Script fb:purpose="styling">
        <![CDATA[
        import mx.core.FlexVersion;

        private var paddingChanged:Boolean;

        /* Define the skin elements that should not be colorized. */
        static private const exclusions:Array = ["background", "textDisplay", "promptDisplay", "border"];

        /* exclusions before Flex 4.5 for backwards-compatibility purposes */
        static private const exclusions_4_0:Array = ["background", "textDisplay", "promptDisplay"];

        /**
         * @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;
        }

        /* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
        static private const contentFill:Array = ["bgFill"];

        /**
         *  @private
         */
        override public function get contentItems():Array {return contentFill};

        /**
         *  @private
         */
        override protected function commitProperties() : void
        {
            super.commitProperties();

            if (paddingChanged)
            {
                updatePadding();
                paddingChanged = false;
            }
        }

        /**
         * @private
         */
        override protected function initializationComplete() : void
        {
            useChromeColor = false;
            super.initializationComplete();
        }

        /**
         *  Update the display list.
         * 
         *  @private
         */
        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
        {
            var visibleState:Boolean = (getStyle("borderVisible") == true) ? true : false;
            border.visible = visibleState;
            shadow.visible = visibleState;

            if(currentState == 'focused')
            {
                focusBorder.visible = getStyle("focusBorderVisible");
                focusBorderStroke.color = getStyle("focusBorderColor");
                focusBorderStroke.alpha = getStyle("focusBorderAlpha");
            }
            else
            {
                borderStroke.color = getStyle("borderColor");
                borderStroke.alpha = getStyle("borderAlpha");
            }

            super.updateDisplayList(unscaledWidth, unscaledHeight);
        }

        /**
         *  Adjusts the border to be visible and within' the bounds.
         * 
         *  @private
         */
        private function updateBorderPos() : void
        {
            if(getStyle("borderVisible") == true || getStyle("focusBorderVisible") )
            {
                background.left = background.top = background.right = background.bottom = 1;
                textDisplay.left = textDisplay.top = textDisplay.right = textDisplay.bottom = 1;
                if(labelDisplay)
                {
                    labelDisplay.setLayoutBoundsSize(unscaledWidth - 2, unscaledHeight - 2);
                    labelDisplay.setLayoutBoundsPosition(1, 1);
                }
            }
            else
            {
                background.left = background.top = background.right = background.bottom = 0;
                textDisplay.left = textDisplay.top = textDisplay.right = textDisplay.bottom = 0;
                if(labelDisplay)
                {
                    labelDisplay.setLayoutBoundsSize(unscaledWidth, unscaledHeight);
                    labelDisplay.setLayoutBoundsPosition(0, 0);
                }
            }
        }

        /**
         *  Adds the padding properties to the controls.
         * 
         *  @private
         */
        private function updatePadding() : void
        {
            var sides:Array = [ "Top", "Right", "Bottom", "Left" ];
            var padding:Number;
            var paddingStr:String;
            var paddingArr:Array;
            var paddingLen:Number
            var side:Number;
            var i:String;

            /* Set the padding on the textDisplay control.
            This will also support for the individual paddingTop,
            paddingRight, [...] properties and they will override
            the short-hand padding property. */
            if(textDisplay)
            {
                paddingStr = getStyle("padding");
                if(paddingStr != null)
                {
                    paddingArr = paddingStr.replace(/^\s+|\s+$/g, '').split(" ");
                    paddingLen = paddingArr.length;

                    for(i in sides) 
                    {
                        side = (paddingLen == 3 && side == 2) ? 1 : Number(i) % paddingLen;

                        if(textDisplay.getStyle("padding" + sides[i]) != paddingArr[side])
                        {
                            textDisplay.setStyle("padding" + sides[i], parseInt(paddingArr[side]));
                        }
                    }
                }

                for (i in sides) 
                {
                    padding = getStyle("padding" + sides[i]);

                    if(!isNaN(padding) && textDisplay.getStyle("padding" + sides[i]) != padding)
                        textDisplay.setStyle("padding" + sides[i], padding);
                }
            }

            /* Set the padding on the labelDisplay control. */
            if(labelDisplay)
            {
                paddingStr = getStyle("labelPadding");
                if(paddingStr != null)
                {
                    paddingArr = paddingStr.replace(/^\s+|\s+$/g, '').split(" ");
                    paddingLen = paddingArr.length;

                    for (i in sides) 
                    {
                        side = (paddingLen == 3 && side == 2) ? 1 : Number(i) % paddingLen;
                        if(labelDisplay.getStyle("padding" + sides[i]) != paddingArr[side])
                            labelDisplay.setStyle("padding" + sides[i], paddingArr[side]);
                    }
                }
            }
        }

        /**
         *  @private
         */
        override public function styleChanged(styleProp:String):void
        {
            var allStyles:Boolean = !styleProp || styleProp == "styleName";

            super.styleChanged(styleProp);

            if (allStyles || styleProp.indexOf("padding") == 0)
            {
                paddingChanged = true;
                invalidateProperties();
            }
        }
        ]]>
    </fx:Script>

    <fx:Script>
        <![CDATA[
        /** 
         * @private 
         */     
        private static const focusExclusions:Array = ["textDisplay"];

        /**
         *  @private
         */
        override public function get focusSkinExclusions():Array { return focusExclusions;};
        ]]>
    </fx:Script>

    <s:states>
        <s:State name="normal"/>
        <s:State name="focused"/>
        <s:State name="disabled" stateGroups="disabledStates"/>
        <s:State name="normalWithPrompt"/>
        <s:State name="disabledWithPrompt" stateGroups="disabledStates"/>
    </s:states>

    <!-- border --> 
    <!--- @private -->
    <s:Rect left="0" right="0" top="0" bottom="0" id="border" radiusX="3" excludeFrom="focused">
        <s:stroke>     
            <!--- @private -->
            <s:SolidColorStroke id="borderStroke" weight="1" />
        </s:stroke>
    </s:Rect>  

    <!-- focusBorder --> 
    <!--- @private -->
    <s:Rect left="0" right="0" top="0" bottom="0" id="focusBorder" radiusX="3" includeIn="focused">
        <s:stroke>     
            <!--- @private -->
            <s:SolidColorStroke id="focusBorderStroke" weight="1" />
        </s:stroke>
    </s:Rect>

    <!-- fill -->
    <!--- Defines the appearance of the TextInput component's background. -->
    <s:Rect id="background" left="1" right="1" top="1" bottom="1" radiusX="3">
        <s:fill>
            <!--- @private Defines the background fill color. -->
            <s:SolidColor id="bgFill" color="0xFFFFFF" />
        </s:fill>
    </s:Rect>

    <!-- shadow -->
    <!--- @private -->
    <s:Rect left="1" top="1" right="1" height="1" id="shadow" radiusX="3">
        <s:fill>
            <s:SolidColor color="0x000000" alpha="0.12" />
        </s:fill>
    </s:Rect>

    <s:HGroup gap="0">
        <!--- Defines the Label that is used for prompt text. The includeInLayout property is false so the prompt text does not affect measurement. -->
        <s:Label id="labelDisplay"/>

        <!-- text -->
        <!--- @copy spark.components.supportClasses.SkinnableTextBase#textDisplay -->
        <s:RichEditableText id="textDisplay"
                  verticalAlign="middle"
                  widthInChars="20"/>
    </s:HGroup>

</s:SparkSkin>
EN

回答 1

Stack Overflow用户

发布于 2014-03-22 12:56:10

在skinClass...increse “gap”标签和editableText...then检查之间的值.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22574032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档