实现Flex HotKey 键盘四个方向键(Navigation)导航功能

来源:互联网 发布:云计算与大数据前景 编辑:程序博客网 时间:2024/05/18 00:52

最近做的Flex项目,客户需要Flex做出来的UI能像Excel一样全键盘操作,除了Tab加Enter之外,特别需要能够支持四个方向键的操作支持,就像是Excel一样,当单元格中的文字处于全选状态的时候可以通过方向键进行导航.


上图是我做的例子截图,这个例子中,上面6个是TextInput,下面是可编辑的DataGrid。

当光标选中第一个textinput的时候,我们让它自动选择全部文字,通过setSelection()函数来实现,之后点击键盘的右方向键(KeyBoard.RIGHT)时,焦点会到第二个input中,一次类推,一直到input6的时候,再按右方向键会跳到DataGrid的第一个可编辑单元。

另外还支持了其他3个方向键的操作(KeyBoard.LEFT, KeyBoard.UP, KeyBoard.DOWN).

这里附上程序代码,希望能对大家有所帮助。但有一点需要说明的是,这里的6个TextInput控件之间的顺序是我硬编码的,可扩展性差,如果碰到输入控件数量不定或者位置不定,那就需要自己动手写个灵活的控制器了。这里仅提供一个可行性参考。

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
  xmlns:s="library://ns.adobe.com/flex/spark" 
  xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import flash.events.*;
import mx.managers.FocusManager;
[Bindable]
private var dp:Array = [{ssn:"123-123-1234",firstName:"John",lastName:"Doe",address:"San Francisco",zip:"98765"},
{ssn:"789-789-7890",firstName:"Mary",lastName:"Roe",address:"San Francisco",zip:"12345"},
{ssn:"555-222-3434",firstName:"Jack",lastName:"Chaw",address:"Newton",zip:"02135"},
{ssn:"555-883-6666",firstName:"Nick",lastName:"Ted",address:"Boston",zip:"66666"}];

public function onFocusInput(event:FocusEvent):void {
var comp:TextInput = event.currentTarget as TextInput;
comp.setSelection(0, String(event.target.text).length);
}

private function handleKeyDown_dg(event:KeyboardEvent):void
{
//get the datagrid's current edit item position
var v:Object = dg.editedItemPosition;
//get the instance editor of datagrid
var ti:TextInput = TextInput(dg.itemEditorInstance);

//according to the keydow to navigate next item
if(event.keyCode == Keyboard.DOWN){
if(v.rowIndex < dg.dataProvider.length -1){
v.rowIndex++;
dg.editedItemPosition = v;
}
else
event.preventDefault();
}else if(event.keyCode == Keyboard.UP){
if(v.rowIndex > 0){
v.rowIndex --;
dg.editedItemPosition = v;
}else
input6.setFocus();
}
if(event.keyCode == Keyboard.LEFT){
if(ti.selectionBeginIndex == 0 && ti.selectionEndIndex == ti.text.length){
if(v.columnIndex > 0)
v.columnIndex --;
}
dg.editedItemPosition = v;
}else if(event.keyCode == Keyboard.RIGHT){

if(v.columnIndex < dg.columns.length -1 && ti.selectionBeginIndex ==0 && ti.selectionEndIndex == ti.text.length)
v.columnIndex ++;
dg.editedItemPosition = v;
}

}                
private function isSelectAll(obj:TextInput):Boolean{
if(obj.selectionBeginIndex == 0 && obj.selectionEndIndex == obj.text.length)
return true
return false;
}                
private function handleKeyDown_textinput1(event:KeyboardEvent):void
{
switch(event.keyCode){
case Keyboard.RIGHT :
if(isSelectAll(input1)){
input2.setFocus();
}
break;
case Keyboard.DOWN :
if(isSelectAll(input1)){
input4.setFocus();
}
break;
}                                  
}
private function handleKeyDown_textinput2(event:KeyboardEvent):void
{
switch(event.keyCode){
case Keyboard.LEFT :
if(isSelectAll(input2)){
input1.setFocus();
}
break;
case Keyboard.RIGHT :
if(isSelectAll(input2)){
input3.setFocus();
}
break;
case Keyboard.DOWN :
if(isSelectAll(input2)){
input5.setFocus();
}
break;
}                                  
}                
private function handleKeyDown_textinput3(event:KeyboardEvent):void
{
switch(event.keyCode){
case Keyboard.LEFT :
if(isSelectAll(input3)){
input2.setFocus();
}
break;
case Keyboard.RIGHT :
if(isSelectAll(input3)){
input4.setFocus();
}
break;
case Keyboard.DOWN :
if(isSelectAll(input3)){
input6.setFocus();
}
break;
}                                  
}
private function handleKeyDown_textinput4(event:KeyboardEvent):void
{
switch(event.keyCode){
case Keyboard.LEFT :
if(isSelectAll(input4)){
input3.setFocus();
}
break;
case Keyboard.RIGHT :
if(isSelectAll(input4)){
input5.setFocus();
}    
break;
case Keyboard.UP :
if(isSelectAll(input4)){
input1.setFocus();
}    
break;                 
}                                  
}
private function handleKeyDown_textinput5(event:KeyboardEvent):void
{
switch(event.keyCode){
case Keyboard.LEFT :
if(isSelectAll(input5)){
input4.setFocus();
}
break;
case Keyboard.RIGHT :
if(isSelectAll(input5)){
input6.setFocus();
}
break;
case Keyboard.UP :
if(isSelectAll(input5)){
input2.setFocus();
}
break;
}                                  
}
private function handleKeyDown_textinput6(event:KeyboardEvent):void
{
switch(event.keyCode){
case Keyboard.LEFT :
if(isSelectAll(input6)){
input5.setFocus();
}
break;
case Keyboard.RIGHT :
if(isSelectAll(input6)){
dg.setFocus();
dg.editedItemPosition={columnIndex:0,rowIndex:0};
}
break;
case Keyboard.UP :
if(isSelectAll(input6)){
input3.setFocus();
}
break;
}                                  
}

]]>
</fx:Script>

<mx:Panel width="100%" height="100%" id="pPanel" title="HotKey Demo(LEFT,RIGHT,UP,DOWN) like Excel">     
<mx:Grid >
<mx:GridRow>
<mx:GridItem>
<mx:TextInput id="input1" text="input1" width="120" height="20" textAlign="right"   keyDown="handleKeyDown_textinput1(event)" focusIn="onFocusInput(event)" />
</mx:GridItem>
<mx:GridItem>
<mx:TextInput id="input2" text="input2" width="120" height="20" textAlign="right"  keyDown="handleKeyDown_textinput2(event)" focusIn="onFocusInput(event)" />   
</mx:GridItem>
<mx:GridItem>
<mx:TextInput id="input3" text="input3" width="120" height="20"  textAlign="right"  keyDown="handleKeyDown_textinput3(event)" focusIn="onFocusInput(event)" />
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem>
<mx:TextInput id="input4" text="input4" width="120" height="20"   textAlign="right"  keyDown="handleKeyDown_textinput4(event)" focusIn="onFocusInput(event)" />
</mx:GridItem>
<mx:GridItem>
<mx:TextInput id="input5" text="input5" width="120" height="20" textAlign="right"  keyDown="handleKeyDown_textinput5(event)" focusIn="onFocusInput(event)"/>
</mx:GridItem>
<mx:GridItem>
<mx:TextInput id="input6" text="input6" width="120" height="20"  textAlign="right"     keyDown="handleKeyDown_textinput6(event)" focusIn="onFocusInput(event)" />
</mx:GridItem>
</mx:GridRow>
</mx:Grid> 
<mx:DataGrid   id="dg" selectable="false"  width="100%" height="100%" dataProvider="{dp}" keyDown="handleKeyDown_dg(event)" paddingTop="0" paddingBottom="0" paddingLeft="0" paddingRight="0" editable="true" dragEnabled="false" sortableColumns="false" resizableColumns="true" draggableColumns="false" >
<mx:columns>
<mx:DataGridColumn dataField="ssn" headerText="Regional Division" width="270"  editable="true"/>
<mx:DataGridColumn dataField="firstName" headerText="firstName" width="120" textAlign="right"  editable="true"/>
<mx:DataGridColumn dataField="lastName" headerText="lastName" width="110" textAlign="right"  editable="true"/>
<mx:DataGridColumn dataField="address" headerText="address" width="105"  textAlign="right" editable="true"/>
<mx:DataGridColumn dataField="zip" headerText="zip" width="105" textAlign="right"  editable="true"/>
</mx:columns>
</mx:DataGrid>
</mx:Panel>
</s:WindowedApplication>


http://wmcai.blog.163.com/blog/static/4802420086169146830/