我试着弄清楚焦点机制在Flex中是如何工作的。这是我的意思的例子:
假设我们有一个简单的Web应用程序,其中包含扩展Canvas
并实现mx.managers.IFocusManagerComponent
的自定义组件。此组件会覆盖focusInHandler
和focusOutHandler
方法,并显示有关如何调用它们的一些反馈(更薄或更粗的边框)。此自定义组件还包含一些Text
。
该组件的来源是:
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100" height="100" creationComplete="cc();" implements="mx.managers.IFocusManagerComponent">
<mx:Script>
<![CDATA[
import mx.containers.Canvas;
import mx.controls.Text;
import mx.controls.TextArea;
import mx.core.UIComponent;
import mx.managers.IFocusManagerComponent;
public function cc():void
{
text = new Text;
text.text = "123";
addChild(text);
setStyle("backgroundColor", "0xddddff");
setStyle("borderColor", "0x000000");
setStyle("borderThickness", 1);
setStyle("borderStyle", "solid");
}
private var text:Text;
override protected function focusInHandler(e:FocusEvent):void {
trace("focusInHandler, currFocus: " + focusManager.getFocus());
setStyle("borderThickness", 4);
}
override protected function focusOutHandler(e:FocusEvent):void {
trace("focusOutHandler, currFocus: " + focusManager.getFocus());
setStyle("borderThickness", 1);
}
]]>
</mx:Script>
</mx:Canvas>
以下是实时版本(包含源视图):http://rafalrybacki.com/lab/focus_question/。在应用程序中,TextArea
下面还有一个Canvas
- 以便在测试时简化焦点操作。
问题:
如果您在紫色画布上单击一次,它将获得焦点(focusInHandler
被调用),然后如果再次单击,焦点将丢失(focusOutHandler
调用) - 为什么?
点击Text
Canvas
获得焦点(focusInHandler
已调用)并点击该区域的任何地方(focusOutHandler
nevet ) - 为什么?
也许我对整个焦点问题的理解是错误的? 感谢您提出任何建议。
尊重,
拉法尔
答案 0 :(得分:1)
嘿Rafalrybacki。 [我正在参加一个会议,并不能真正花时间在这个问题上,但我认为我可以用一两个指针来帮助:]
首先,Canvas的目的是与FocusManager交互,而不是实现IFocusManagerComponent的组件。 Canvas实现了IFocusManagerContainer,虽然你可以通过使容器成为IFocusManagerComponent来完成你想要完成的任务,但我会避免它,因为我尝试做那些我认为flex sdk团队在使用内部组件时所期望的。
我认为他们打算在你的容器中收听FocusEvent。默认情况下,FocusEvents会出现气泡,因此您可以使用简单的事件侦听器完成所需的大部分操作。
注意:收听focusOut可能会使具有多个uicomponents作为子节点的组件变得混乱 - 即组合框具有UITextField和Button,因此组件具有多个FocusOut和FocusIn事件,这些事件发生在同一组件中。你的救世主会(我猜)在focusManger.getFocus()项目上做一个container.contains()(把它等等)来准确设置你的风格。
我只是责备,所以如果你需要一些帮助,或者想了解更多关于为什么在调度时派遣了focusIn或focusOut evt的话 - 我很乐意将一些代码拼凑起来你解释为什么要抓住事件的类型。你最好的选择是(适合flex sdk指南)是使用容器内的事件监听器,而不是与同时是IFocusManagerComponent和IFocusManagerContainer的组件对抗。可能会变得混乱。
希望有所帮助。祝你好运, 杰里米