加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

浅析 Flex中的Focus

发布时间:2020-12-15 01:31:52 所属栏目:百科 来源:网络整理
导读:关键字:focus、 setFocus、 IFocusManager、KeyboardEvent 焦点、设置焦点、获得焦点、键盘事件 一、无焦点的困扰——组件监听不到键盘事件 原因:只有获得焦点的组件(确切说是InteractiveObject)才能监听到键盘事件的目标阶段;键盘事件(flash.events.K
关键字:focus、 setFocus、 IFocusManager、KeyboardEvent
焦点、设置焦点、获得焦点、键盘事件


一、无焦点的困扰——组件监听不到键盘事件
原因:只有获得焦点的组件(确切说是InteractiveObject)才能监听到键盘事件的目标阶段;键盘事件(flash.events.KeyboardEvent)参与冒泡阶段,所以焦点组件的父项(以及它爸爸的爸爸的爸爸……)亦可在事件的冒泡阶段监听到该事件。
简单来说:只有组件本身或者其子孙项获得焦点后,才能监听到键盘事件。

二、获得焦点

1、设置焦点——setFocus()
Flex 的UIComponent 的setFocus() 方法可以设置焦点;调用此方法最终会将自身赋值给 systemManager.stage.focus
另外还可以采用focusManager.setFocus(IFocusManagerComponent) 给组件设置焦点;

2、 swf 获得焦点
如果swf嵌入到html中,首先要保证该swf在DOM中获得焦点;[code=“JavaScript”] document.getElementById([swfId]).focus(); 为方便起见,可直接修改 flex 的模板 index.template.html;[code=“JavaScript”]
<body scroll="no" onload=’document.getElementById("${application}").focus();’>
(详见附件的模板文件)

3、注意焦点转移
需要注意的时,随着swf与用户的交互 或者 弹出Alert窗框或者Popup组件、抑或是某些代码执行 都有可能引起焦点的转移;如果有需要便要采用setFocus() 重设焦点。

4、鼠标点击获得焦点
——我更希望组件能够像TextInput那样鼠标点击即可获得焦点
——很简单监听 MouseEvent.MOUSE_DOWN 然后setFoucus() 即可;
——不!有更简单的,只需让你的组件实现 IFocusManagerComponent 接口即可。
UIComponent 已经实现了 IFocusManagerComponent 接口,只是没有显示的标明而已,所以需要某组件具有鼠标点击获得焦点的功能时,只需 显示声明 implements IFocusManagerComponent 即可。当然有特殊需求的还要覆盖某些方法,比方TextInput 就覆盖了 setFocus() 方法。(具体见源码。)
例如:让图片具有点击获得焦点特性:[code=“ActionScript”]
public class MyImage extends Image implements IFocusManagerComponent {
public function MyImage() { super();}
}
该例子详见附件。
下面会介绍 IFocusManagerComponent 接口,并研究 究竟如何实现鼠标点击获得焦点的。

5、例外
如果只监听整个应用的键盘事件,不需具体到某个组件,可以考虑用给 stage添加监听,这样就不用考虑烦人的焦点问题。

三、介绍IFocusManagerComponent

见API文档,从focusManager.setFocus(IFocusManagerComponent) 顺藤摸瓜,某些组件已经实现了IFocusManagerComponent 接口。

包 mx.managers.IFocusManagerComponent

Interface public interface IFocusManagerComponent
实现器 Accordion,AdvancedListBase,Button,ButtonBar,ChartBase,ComboBase,DateChooser,DateField,HTML,ListBase,MenuBar,NumericStepper,TabNavigator,TextArea,TextInput,UIMovieClip


IFocusManagerComponent 接口用于定义一些接口,可获得焦点的组件必须实现这些接口才能从 FocusManager 获得焦点。UIComponent 类中提供了此接口的基本实现,但 UIComponent 并不实现完整的 IFocusManagerComponent 接口,因为部分 UIComponent 无需获得焦点。因此,要使 UIComponent 派生的组件成为一个可获得焦点的有效组件,只需将“implements IFocusManagerComponent”添加到类定义即可。

四、鼠标按下获得焦点分析。

当FocusManager被激活时,会给其管辖容器添加监听器:[code=“ActionScript”]
form.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
监听器代码摘要:[code=“ActionScript”]
private function mouseDownHandler(event:MouseEvent):void??? {

???????? if (event.isDefaultPrevented())???? return;

//从事件目标开始查找顶级的实现可设置焦点的组件
??????? var o:DisplayObject = getTopLevelFocusTarget(
??????????? InteractiveObject(event.target));

??????? if (!o)??? return;??????
???????
??????? if ((o != _lastFocus || lastAction == "ACTIVATE") && !(o is TextField))
??????????? setFocus(IFocusManagerComponent(o));
}
/**
???? *? 从传入的对象开始向其父项方向查找顶级的实现可设置焦点的组件
???? */[code=“ActionScript”]
private function getTopLevelFocusTarget (o:InteractiveObject):InteractiveObject?? {

//此处可以看到可设置焦点的组件需要满足的几个条件:
??????? while (o != InteractiveObject(form))? {
??????????? if (o is IFocusManagerComponent &&
??????????????? IFocusManagerComponent(o).focusEnabled &&
??????????????? IFocusManagerComponent(o).mouseFocusEnabled &&
??????????????? (o is IUIComponent ? IUIComponent(o).enabled : true))
??????????????? return o;

// if we cross a boundry into a bridged application,then return null so
// the target is only processed at the lowest level
if (o.parent is ISWFLoader) {
if (ISWFLoader(o.parent).swfBridge)
return null;
}
??????????? o = o.parent;

??????????? if (o == null)
??????????????? break;??????
}
return null;
}
受FocusManger管理的组件的几个条件:
1、实现 IFocusManagerComponent
2、focusEnabled、mouseFocusEnabled、enabled三个属性皆为true
3、bridge情况下(还不了解bridge 请大侠zhijiao)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读