正确防止Flex Mobile应用程序中的方向更改
有没有人能够在Flex SDK 4.6中正确地工作?
这是一个简短的片段:
<?xml version="1.0" encoding="utf-8"?> <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" addedToStage="onAddedToStage(event)" title="Title"> <fx:Script> <![CDATA[ private function onAddedToStage(event:Event):void { if (stage.autoOrients) { stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging, false, 0, true); } } private function orientationChanging(event:StageOrientationEvent):void { if (event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN) { event.preventDefault(); } } ]]> </fx:Script> </s:View>
我想要实现的是在两个方向都支持横向模式,所以如果用户将设备旋转180度,屏幕也应该旋转。 但是当用户将设备旋转到纵向方向时,根本不应该有任何操作。 相反,我看到了导航器操作栏的宽度更改,有时候还是纵向内容,所以显然阻止事件是不够的。 我使用Adobebuild议的“官方”方式,但问题在于它不能很好地工作。 当然,舞台并没有改变,但似乎总有一些东西在导航仪中发射,因为你可以看到动作条宽度的变化。
我已经成功地将layoutbounds设置为处理方法中的固定宽度 – 这可以防止更改操作栏宽度,但这只是一个临时解决scheme – 如果视图是过渡对象或其他重绘对象,则会再次渲染大小。 就好像下面有些东西说的是纵向模式,尽pipe我试图阻止它。
在引爆“autoOrient = false”之类的愚蠢想法之前,请不要。 这显然不是解决这个问题的方法。 显然这是Flex SDK的一个错误 – 有没有人find解决方法或稳定的解决方法?
编辑:显然是其他人碰到类似的问题:
– http://forums.adobe.com/message/3969531 (主题是关于别的东西,但读魔术机器人的评论)
– http://forums.adobe.com/message/4130972
我不确定这是否是正确的,最终我做了什么错误的事情,但是经过很多的努力,我发现这是一个稳定的解决scheme:
private function onAddedToStage(event:Event):void { if (stage.autoOrients) { stage.removeEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging); stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging, false, 100, true); } } private function orientationChanging(event:StageOrientationEvent):void { event.stopImmediatePropagation(); if (event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN) { event.preventDefault(); } }
首先要注意的是,在移动应用程序中,addedToStage会触发几次(2-3次)。 我不知道为什么,显然,我的代码中没有addChild。 也许AIR运行时会做其他的事情。 因此,为了避免增加不必要的处理程序数量,常用的技术是首先删除处理程序 – 如果这样的处理程序尚未注册,那么它将不会执行任何操作,但是如果有,它将删除它,这将保持处理程序的计数1。
第二件事是事件的优先级 – 它不会在0上工作,它必须设置在一个大的东西上,以在AIR运行时之前启动。
最后一件事 – event.stopImmediatePropagation() – 现在,我们是第一个处理事件,我们不能阻止这个事件发送进一步在这个特定的场景。
这一起使得方向无法完美地工作 – 对我来说,景观和颠倒的风景(rotate_left,rotated_right)正在工作和转换,而肖像模式根本不影响视图。
现在,这里存在危险 – 您可能希望在离开视图时移除监听器(在转换animation结束,查看停用或某事),因为stopImmediatePropagation将阻止事件在应用程序的其他部分处理。
我希望Adobe(或者现在的Apache)能够仔细研究这个问题并追踪我的解决scheme。
编辑
还有这个解决scheme的最后一个问题,就是如果应用程序在设备处于DEFAULT或UPSIDE_DOWN方向时启动,在这种情况下,应用程序将处于纵向模式。
为了解决这个问题,一个解决scheme是改变addedToStage处理程序中的长宽比:
if(Stage.supportsOrientationChange) { stage.setAspectRatio(StageAspectRatio.LANDSCAPE); }
所以我遇到了同样的问题 我想我终于想出了解决办法。 下面我做了什么:
<s:TabbedViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" ...blahblahblah... width="1024"/> protected function tabbedviewnavigatorapplication2_applicationCompleteHandler(event:FlexEvent):void { stage.autoOrients=true; preventOrient(); } private function preventOrient():void { if (stage.autoOrients) { stage.removeEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging); stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging, false, 100, true); } } private function orientationChanging(event:StageOrientationEvent):void { if(event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN || event.afterOrientation == StageOrientation.UNKNOWN) { event.preventDefault(); } }
值得注意的是,在应用程序完成处理程序中,我将stage.autoOrients设置为true,因为在app.xml文件中我将它设置为false,因为有一个启animation面,并且不希望用户在此期间重新定位屏幕。 真的,我所做的唯一不同的是占用StageOrientation.UNKNOWN,并阻止任何可能的操作,在主mxml文件中将宽度设置为1024(对于iPad屏幕,可能与其他平板设备不同),并删除stopMmediatepropagation 。 希望这可以帮助。