AS3实现表单组件焦点备份与恢复的方法咨询
解决Flex表单组件重新打开时恢复焦点的问题
你现在遇到的核心问题是:objTarget只是存储了组件的ID字符串,并不是组件的实例对象,所以直接调用objTarget.setFocus()肯定会报错或者无效——字符串类型根本没有这个方法嘛😉
下面给你两个可行的实现方案,你可以根据自己的需求选择:
方案一:直接存储组件实例(推荐,简单高效)
这个方案适合不需要持久化焦点信息(比如只是窗口关闭再打开,不是重启程序)的场景:
修改变量定义,从存储ID改成存储组件实例:
// 把原来的String类型改成UIComponent,因为你的组件都是它的子类 private var lastFocusedComponent:UIComponent;更新焦点事件处理器,直接存储获焦的组件实例:
protected function memo_focusInHandler(event:FocusEvent):void { lastFocusedComponent = event.currentTarget as UIComponent; }在窗口重新激活/初始化完成时恢复焦点:
比如给窗口添加activate或者creationComplete事件处理器:protected function window_activateHandler(event:Event):void { // 先判断组件是否存在且在显示列表中,避免空引用 if (lastFocusedComponent != null && lastFocusedComponent.parent != null) { lastFocusedComponent.setFocus(); } }
方案二:存储组件ID并持久化(适合需要跨会话保存焦点的场景)
如果需要关闭程序后再打开依然记住最后获焦的组件,就需要把ID存在本地存储里,再通过ID查找组件:
存储获焦组件的ID到本地:
protected function memo_focusInHandler(event:FocusEvent):void { var appSettings:SharedObject = SharedObject.getLocal("FlexAppSettings"); appSettings.data.lastFocusedId = event.currentTarget.id; appSettings.flush(); // 立即写入本地 }实现一个递归查找组件的工具函数(因为组件可能嵌套在容器里,直接getChildByName找不到):
private function findComponentById(parent:DisplayObjectContainer, targetId:String):UIComponent { for (var i:int = 0; i < parent.numChildren; i++) { var child:DisplayObject = parent.getChildAt(i); // 检查当前子组件是否是UIComponent且ID匹配 if (child is UIComponent && (child as UIComponent).id == targetId) { return child as UIComponent; } // 如果是容器,递归查找子容器里的组件 if (child is DisplayObjectContainer) { var foundComponent:UIComponent = findComponentById(child as DisplayObjectContainer, targetId); if (foundComponent != null) { return foundComponent; } } } return null; }在窗口初始化完成时恢复焦点:
protected function window_creationCompleteHandler(event:Event):void { var appSettings:SharedObject = SharedObject.getLocal("FlexAppSettings"); if (appSettings.data.lastFocusedId != null) { var targetComponent:UIComponent = findComponentById(this, appSettings.data.lastFocusedId); if (targetComponent != null) { targetComponent.setFocus(); } } }
几个注意点:
- 一定要确保在调用
setFocus()时,组件已经完全初始化并添加到显示列表中,否则方法不会生效。 - 如果用方案一存储实例,记得在窗口关闭时把
lastFocusedComponent设为null,避免内存泄漏。 - 对于DataGrid这类复杂组件,
setFocus()会让整个组件获焦,如果需要聚焦到具体单元格,你可能需要额外处理,但这个方案已经能满足你“定位到最后获焦组件”的需求。
内容的提问来源于stack exchange,提问作者Flex60460
相关产品推荐
相关产品推荐

