2014-01-27 65 views
4

我在libgdx应用程序中设置了一个包含三个TextField的舞台,在桌面模式和Android模式下我获得了不同的行为。在Android上,输入回车键将光标移动到下一个TextField。在桌面上,输入回车键什么也不做。在Libgdx中输入密钥处理TextField

如何让光标在两个平台上始终如一地移动?我希望能够在用户输入时将焦点设置到另一个字段。在Android上,无论我将焦点置于哪个位置,默认的输入关键行为都会在此之后将焦点跳转到该字段。

这里是我目前使用移动光标并清除下一个字段代码:

stage.addListener(new InputListener() { 
     @Override 
     public boolean keyUp(InputEvent event, int keycode) { 
      if (keycode == Input.Keys.ENTER) { 
       nextField(); 
      } 
      return false; 
     } 
    }); 
    Gdx.input.setInputProcessor(stage); 
} 

private void nextField() { 
    TextField nextField = 
      stage.getKeyboardFocus() == text1 
      ? text2 
      : stage.getKeyboardFocus() == text2 
      ? text3 
      : text1; 
    nextField.setText(""); 
    stage.setKeyboardFocus(nextField); 
} 

我试图取消该事件或从处理方法返回true,但重点还是后移我的代码完成。

我的完整示例代码是on GitHub

回答

3

TextField使用一个私有的内部InputListener,它在构造函数中初始化并且不能轻易被覆盖。改变焦点的相关代码是这样的监听器的方法的keyTyped期间:

public boolean keyTyped (InputEvent event, char character) { 
    [...] 
    if ((character == TAB || character == ENTER_ANDROID) && focusTraversal) 
     next(Gdx.input.isKeyPressed(Keys.SHIFT_LEFT) || Gdx.input.isKeyPressed(Keys.SHIFT_RIGHT)); 
    [...] 
} 

一个简单的解决办法是禁用焦点遍历所有在一起,并设置一个com.badlogic.gdx.scenes.scene2d.ui.TextFieldListener即自动执行遍历来代替:

TextField textField 
textField.setFocusTraversal(false); 
textField.setTextFieldListener(new TextFieldListener() { 
    @Override 
    public void keyTyped(TextField textField, char key) { 
     if ((key == '\r' || key == '\n')){ 
      textField.next(Gdx.input.isKeyPressed(Keys.SHIFT_LEFT) || Gdx.input.isKeyPressed(Keys.SHIFT_RIGHT)); 
     } 
    } 
}); 

如果您需要能够启用和使用的TextField setFocusTraversal方法禁用焦点遍历,也将是一个非常哈克解决方案通过包装自己的监听器里面的内部InputListener时被添加到TextField中(但我会而不是推荐此):

class MyTextField extends TextField{ 

class InputWrapper extends InputListener{ 
    private final InputListener l; 

    public InputWrapper(InputListener l) { 
     super(); 
     this.l = l; 
    } 

    @Override 
    public boolean handle(Event e) { 
     return l.handle(e); 
    } 

    @Override 
    public boolean touchDown(InputEvent event, float x, float y, 
      int pointer, int button) { 
     return l.touchDown(event, x, y, pointer, button); 
    } 

    @Override 
    public void touchUp(InputEvent event, float x, float y, 
      int pointer, int button) { 
     l.touchUp(event, x, y, pointer, button); 
    } 

    @Override 
    public void touchDragged(InputEvent event, float x, float y, 
      int pointer) { 
     l.touchDragged(event, x, y, pointer); 
    } 

    @Override 
    public boolean mouseMoved(InputEvent event, float x, float y) { 
     return l.mouseMoved(event, x, y); 
    } 

    @Override 
    public void enter(InputEvent event, float x, float y, int pointer, 
      Actor fromActor) { 
     l.enter(event, x, y, pointer, fromActor); 
    } 

    @Override 
    public void exit(InputEvent event, float x, float y, int pointer, 
      Actor toActor) { 
     l.exit(event, x, y, pointer, toActor); 
    } 

    @Override 
    public boolean scrolled(InputEvent event, float x, float y, 
      int amount) { 
     return l.scrolled(event, x, y, amount); 
    } 

    @Override 
    public boolean keyDown(InputEvent event, int keycode) { 
     return l.keyDown(event, keycode); 
    } 

    @Override 
    public boolean keyUp(InputEvent event, int keycode) { 
     return l.keyUp(event, keycode); 
    } 
    @Override 
    public boolean keyTyped(InputEvent event, char character) { 
     if (isDisabled()) { 
      return false; 
     } else if ((character == '\r' || character == '\n')){ 
      next(Gdx.input.isKeyPressed(Keys.SHIFT_LEFT) || Gdx.input.isKeyPressed(Keys.SHIFT_RIGHT)); 
      return true; 
     } 
     return l.keyTyped(event, character); 
    } 

} 

public MyTextField(String text, Skin skin, String styleName) { 
    super(text, skin, styleName); 
} 

public MyTextField(String text, Skin skin) { 
    super(text, skin); 
} 

public MyTextField(String text, TextFieldStyle style) { 
    super(text, style); 
} 

boolean initialized = false; 
@Override 
public boolean addListener (EventListener l) { 
    if (!initialized) { 
     if (!(l instanceof InputListener)) { 
      throw new IllegalStateException(); 
     } 
     initialized = true; 
     return super.addListener(new InputWrapper((InputListener) l)); 
    } 
    return super.addListener(l); 
} 
} 

编辑: 退一步讲,你也可以与第一个解决方案通过在调用此方法只覆盖文本字段的setFocusTraversal和启用/禁用自己的听众做。

+0

箭头后,我想禁用焦点遍历将完成我所需要的。谢谢。 –

+0

它工作,我已经更新了我的[示例代码](https://github.com/donkirkby/vograbulary/blob/enter-key-traversal/vograbulary/src/com/github/donkirkby/vograbulary/VograbularyGame。java#L31)来包含它。赏金是你的。 –

0

我发现了一个解决方法,但我仍然会欣赏一个更清晰的解决方案,它可以使两个平台的行为方式相同。

我添加了一个标志来指示焦点是否会默认移动,如果焦点不能自行移动,我只会改变焦点。然后我为Android设置MainActivity类,或者为桌面设置Main类。我已发布完整的示例代码on GitHub

private void nextField() { 
    TextField nextField = 
      stage.getKeyboardFocus() == text1 
      ? text2 
      : stage.getKeyboardFocus() == text2 
      ? text3 
      : text1; 
    nextField.setText(""); 
    if (! isFocusMovedAutomatically) { 
     stage.setKeyboardFocus(nextField); 
    } 
} 
0

GDX-1.9.4我能做到以下几点:

final TextField newMessageTextField = new TextField("", uiSkin){ 
    @Override 
    protected InputListener createInputListener() { 
     return new TextFieldClickListener(){ 
      @Override 
      public boolean keyUp(com.badlogic.gdx.scenes.scene2d.InputEvent event, int keycode) { 
       System.out.println("event="+event+" key="+keycode); 
       return super.keyUp(event, keycode); 
      }; 
     }; 
    } 
}; 

,重点按压文本字段我有

event=keyUp key=19 
event=keyUp key=20 
event=keyUp key=22 
event=keyUp key=21