我正在尝试在flex4中创建一个可编辑的标签。
要做到这一点,我正在扩展textfield类,因此它包含一个标签控件元素。但是,一旦文本字段变得不可见,我就无法看到标签。
代码看起来像这样:
package unimap.components
{
import spark.components.Label;
import spark.components.TextInput;
public class SmartTextInput extends TextInput
{
private var _label:Label;
public function SmartTextInput()
{
super();
}
public override function set editable(value:Boolean):void
{
super.editable = value;
if (value == false)
{
_label = new Label();
_label.x = this.x;
_label.y = this.y;
_label.width = this.width;
_label.height = this.height;
_label.text = "Home";
addChild( _label ); // This lines fail the code with error
// Error: addChild() is not available in this class. Instead, use addElement() or modify //the skin, if you have one.
}
super.visible = false;
trace("Editable")
}
}
}
但如果我将addChild更改为addElement,我将看到以下错误: 1180:调用可能未定义的方法addElement。
有人可以建议我做错了什么吗?
答案 0 :(得分:5)
这是我在生产系统中使用的解决方案:
package com.npacemo.component
{
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
import mx.core.UIComponent;
import spark.components.Label;
import spark.components.PopUpAnchor;
import spark.components.TextInput;
import spark.components.supportClasses.SkinnableComponent;
[Event(name="change", type="flash.events.Event")]
public class EditableLabel extends SkinnableComponent
{
[SkinState("normal")]
[SkinState("selected")]
[SkinPart(required="true")]
public var labelComponent:Label;
[SkinPart(required="true")]
public var inputAnchor:PopUpAnchor;
[SkinPart(required="true")]
public var inputComponent:UIComponent;
[Bindable]
public var text:String;
public function EditableLabel()
{
addEventListener(MouseEvent.CLICK, handleDisplayLabelClick);
}
override protected function partAdded(partName:String, instance:Object):void
{
if (instance == labelComponent)
{
labelComponent.addEventListener(MouseEvent.CLICK, handleDisplayLabelClick);
}
else if (instance == inputComponent)
{
inputComponent.addEventListener(Event.CHANGE, handleInputComponentChange);
inputComponent.addEventListener(KeyboardEvent.KEY_DOWN, handleTextInputKeyDown);
inputComponent.addEventListener(FocusEvent.FOCUS_OUT, handleInputComponentFocusOut);
}
}
private function handleInputComponentChange(e:Event):void
{
text = (inputComponent as TextInput).text;
dispatchEvent(e.clone());
}
private function handleDisplayLabelClick(event:MouseEvent):void
{
skin.currentState = "selected";
stage.addEventListener(MouseEvent.CLICK, handleStageClick);
}
private function handleStageClick(e:MouseEvent):void
{
if (!inputComponent.hitTestPoint(stage.mouseX, stage.mouseY))
{
stage.removeEventListener(MouseEvent.CLICK, handleStageClick);
skin.currentState = "normal";
}
}
private function handleTextInputKeyDown(event:KeyboardEvent):void
{
if (event.charCode == Keyboard.ENTER)
{
stage.removeEventListener(MouseEvent.CLICK, handleStageClick);
skin.currentState = "normal";
}
}
private function handleInputComponentFocusOut(event:FocusEvent):void
{
stage.removeEventListener(MouseEvent.CLICK, handleStageClick);
skin.currentState = "normal";
}
}
}
这是一个样本皮肤组件:
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<!-- host component -->
<fx:Metadata>
[HostComponent("com.npacemo.component.EditableLabel")]
</fx:Metadata>
<!-- SkinParts
name=inputComponent, type=mx.core.UIComponent, required=true
name=labelComponent, type=spark.components.Label, required=true
-->
<s:states>
<s:State name="normal"/>
<s:State name="selected" enterState="inputComponent.setFocus(); inputComponent.selectRange(inputComponent.text.length, inputComponent.text.length);"/>
</s:states>
<s:transitions>
<s:Transition fromState="*" toState="*" autoReverse="true">
<s:Fade targets="{[labelComponent, inputComponent]}" duration="100"/>
</s:Transition>
</s:transitions>
<s:PopUpAnchor id="inputAnchor" x="-1" y="-7" displayPopUp.normal="false" displayPopUp.selected="true">
<s:TextInput id="inputComponent" text="{hostComponent.text}"
alpha.normal="0" alpha.selected="1"
enabled.normal="false" enabled.selected="true"
width="{labelComponent.width + 20}" focusSkin="{null}"
contentBackgroundColor="0xFBFCA4" borderVisible="false"
fontFamily="Futura" fontSize="12" textAlign="left">
<s:filters>
<s:DropShadowFilter angle="135" alpha="0.5" blurX="10" blurY="10"/>
</s:filters>
</s:TextInput>
</s:PopUpAnchor>
<s:Label id="labelComponent" text="{hostComponent.text}"
alpha.normal="1" alpha.selected="0"
visible.normal="true" visible.selected="false"
verticalCenter="0" width="{this.width+20}" maxDisplayedLines="1"
textDecoration="underline" buttonMode="true"/>
</s:Skin>
答案 1 :(得分:0)
这里有一些问题。一,如果我多次调用enabled = false,我将会有多个标签子项。不是你想要的。您可以基于Group控件构建复合控件并创建自定义外观,但这可能有点过分。我建议只是为TextInput设置外观,并在未启用时将外观更改为看起来像标签(例如,背景和边框上的visible.disabled = false以及主要外观元素上的alpha.disabled = 1.0)这样做的好处是你可以通过CSS应用它并使用默认控件。
答案 2 :(得分:0)
基本上,TextInput不是一个Container,它是一个文本控件组件,因此你不能将子元素添加到它(使用addElement或addChild方法)。
您可以为TextInput创建一个外观,使TextInput“表现”为标签。
告诉我们您对“可编辑标签”的处理方式,这将使我们能够为您提供更好的答案。