[英]How to change tab ordering in Flex (Actionscript, SDK 3.5)
flex选项卡的顺序对于可用性(显而易见)和可访问性(它定义了屏幕阅读器读取顺序)都很重要。 但是,Flex 3.5似乎没有任何支持来影响更复杂的应用程序。
据我所知,到目前为止:
标签排序由mx.managers.FocusManager计算,它负责整个应用程序的一个“标签循环”(即每个容器没有一个,但整个应用程序没有一个)。 嵌入.swf文件和弹出窗口是个例外,每个文件和弹出窗口都有自己的FocusManager。
FocusManager中的逻辑标记为私有,并且该类在Application.initialize()中实例化,因此更改行为并不容易(不能重写SDK的部分,这可能会造成许可证麻烦)
Tab键顺序查找每个组件tabIndex(int)属性。 具有此属性集(> 0)的所有组件按其值排序,否则使用可视层次结构(使用容器内的容器嵌套和子顺序)。
没有tabIndex的所有组件都被排序为在它设置的组件之后(内部,“tabIndex not set”映射到“tabIndex = int.MAX_VALUE”)
具有相同tabIndex的两个组件按可视层次结构排序。
这意味着您可以通过可视化层次结构使用自动排序(主要是您想要的)或者您可以直接使用指定tabIndexes - 但如果您这样做,则完全拧紧自动排序。 如果您使用自定义组件并希望更改其中的选项卡顺序,则这一点尤其糟糕:一旦执行此操作,您就会破坏使用组件的所有屏幕的Tab键顺序。 此外,您不能仅在最高级别的mxml文件上设置选项卡排序,因为您通常无法访问所使用组件的内部工作方式。
accVerticalStuff.mxml
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Label text="One"/>
<mx:TextInput tabIndex="1" id="One" />
<mx:Label text="Two" />
<mx:TextInput tabIndex="2" id="Two"/>
<mx:Label text="Three" />
<mx:TextInput tabIndex="3" id="Three"/>
</mx:VBox>
Application.mxml
预期结果:选项卡顺序首先是左侧的三个垂直项目,然后是右侧的三个垂直项目,即按容器分组。 TopLevelElement是Tab键顺序中的第一个。 (如果没有指定tabIndex,它就会以这种方式正常工作,但是我们无法将tabIndex更改为例如切换One和Three,无论出于何种原因我们可能会这样做)
实际结果:选项卡排序是水平的,即在两个输入表单之间跳转。 TopLevelElement(未指定tabIndex)是Tab键顺序中的最后一个。
更改容器的嵌套在模块化项目中不起作用,更改子项的顺序会影响它们的显示位置(而使用Canvas容器会丢失AutoLayout)。
有没有办法(可能很复杂,但最好不要重写SDK)来指定单个组件的标签排序,而与其他组件无关?
如果所有其他方法都失败了,升级到Flex4有助于解决这个问题吗?
经过一番研究后我发现了以下内容:
DisplayObject
具有tabIndex > 0
则意味着从现在开始按TAB
将仅在使用tabIndex > 0
实例之间切换焦点 tabIndex > 0
只有一个实例,它将永远聚焦 current.tabIndex - next.tabIndex > 1
没关系,tabIndex将增加到下一个现有值 如果多个实例具有相同的tabIndex值,它们将以本机顺序接收焦点(就好像从未定义tabIndex)
-------------------------------------------------- -----------------------------
所以:
用于在某些DisplayObject之间设置TAB导航(无论它们位于显示列表中的哪个位置) - 只需为每个DisplayObject设置tabIndex > 0
即可。
tabIndex = 0
(但如果应用程序中只剩下tabIndex == 0
DisplayObjects - TAB会自然地在它们之间切换焦点)。 tabEnabled = false
应该是更好的选择 以及一些代码(基于您的示例):
showclasses.NewFile.mxml:
<mx:VBox xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:fx="http://ns.adobe.com/mxml/2009" data="1,2,3" creationComplete="addFocuses();">
<fx:Script>
<![CDATA[
private function addFocuses():void{
var focs:Array = data.split(',');
One.tabIndex = focs[0];
Two.tabIndex = focs[1];
Three.tabIndex = focs[2];
}
]]>
</fx:Script>
<mx:Label text="One"/>
<mx:TextInput id="One" />
<mx:Label text="Two" />
<mx:TextInput id="Two"/>
<mx:Label text="Three" />
<mx:TextInput id="Three"/>
</mx:VBox>
Main.mxml:
<mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:th="showclasses.*">
<mx:HBox>
<th:NewFile data="1,2,3" />
<th:NewFile data="1,2,3" />
<th:NewFile data="1,2,3" />
</mx:HBox>
</mx:Application>
如果数据值是1,2,3; 1,2,3; 1,2,3 - 焦点从左向右水平移动(当然因为tabIndex在每一行内是恒定的)然后切换到下一行的左元素。
如果他们是2; 空,3; 0,null,1(对于tabIndex,null == 0) - 焦点将出现在右下角,然后出现在左上角,最后出现在中心。
希望这会有用
我认为www0z0k给出的一些信息不再准确(或者从来没有?)只需阅读tabIndex
属性上的Flex Docs:
指定SWF文件中对象的Tab键顺序。 tabIndex属性默认为-1,表示没有为对象设置制表符索引。
如果SWF文件中当前显示的任何对象包含tabIndex属性,则禁用自动选项卡排序,并从SWF文件中对象的tabIndex属性计算选项卡排序。 自定义选项卡排序仅包括具有tabIndex属性的对象。
tabIndex属性可以是非负整数。 对象根据其tabIndex属性按升序排序。 tabIndex值为1的对象在tabIndex值为2的对象之前。不要对多个对象使用相同的tabIndex值。
tabIndex属性定义的自定义选项卡顺序是平的。 这意味着不需要关注SWF文件中对象的层次关系。 具有tabIndex属性的SWF文件中的所有对象都按Tab键顺序放置,Tab键顺序由tabIndex值的顺序决定。
编辑 :根据我使用Flex 3.3.0的经验,由www0z0k做出的断言#1和#2是错误的。 对于#1,未明确设置tabIndex的控件将始终落在所有按Tab键顺序给出正数的控件之前。 对于#2,然后跟随并且可观察到如果您只设置一个tabIndex,那么一个控件将遵循Tab键顺序中的所有其他自动控件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.