java – 在Libgdx TextField中输入密钥处理

我在我的libgdx应用程序中设置了一个包含三个TextField的舞台,我在桌面模式和Android模式下获得了不同的行为.在Android上,键入enter键会将光标移动到下一个TextField.在桌面上,键入enter键不会执行任何操作.

如何在两个平台上使光标一致移动?我希望能够在用户输入时将焦点设置到另一个字段.在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.

最佳答案
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));
        }
    }
});

如果你需要能够使用TextFields setFocusTraversal方法启用和禁用焦点遍历,那么在将内部InputListener添加到TextField时将内部InputListener包装在自己的侦听器中也会有一个非常糟糕的解决方案(但我不建议这样做):

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,int button) {
        l.touchUp(event,button);
    }

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

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

    @Override
    public void enter(InputEvent event,Actor fromActor) {
        l.enter(event,fromActor);
    }

    @Override
    public void exit(InputEvent event,Actor toActor) {
        l.exit(event,toActor);
    }

    @Override
    public boolean scrolled(InputEvent event,int amount) {
        return l.scrolled(event,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);
}
}

编辑:
再想一想,您也可以通过简单地覆盖TextField的setFocusTraversal并在调用方法期间启用/禁用您自己的侦听器来完成第一个解决方案.

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...