3
\$\begingroup\$

I'm creating a registration screen for my game. I implemented textfields and input is getting correctly. But when I click elsewhere after text is entered, the keyboard stays visible and does not hide automatically, even when a new screen is loaded. Is there any listener methods for hiding the keyboard?

Right now I did a workaround by calling the setOnscreenKeyboardVisible(false) in the sign up and sign in buttons. But I want the keyboard to hide right when it is unfocussed. Is it possible?

UPDATE:

Actually I thought when I click elsewhere the textfield focus changed automatically but that's not the case. The cursor keeps blinking even after the keyboard is hidden explicitly. I edited the correct answer to include this.

\$\endgroup\$
  • \$\begingroup\$ Did you try to add FocusListener to an input text field? \$\endgroup\$ – Jan Tobola Jul 24 '15 at 12:25
  • \$\begingroup\$ I tried that but it's not working. May be I used it wrong: hastebin.com/poravupoto.java \$\endgroup\$ – WeirdElfB0y Jul 25 '15 at 11:04
3
\$\begingroup\$

Try this:

@Override
public void keyboardFocusChanged(FocusEvent event, Actor actor, boolean focused) {
    super.keyboardFocusChanged(event, actor, focused);
    if (!focused)
        setOnscreenKeyboardVisible(false);
}

Otherwise you could go for a better work around. You place a big clickable transparent actor behind everything. When you click anywhere next to your buttons, textfields, etc this field will be triggered and you can get rid of your keyboard ;).

EDIT:

The textfield will remain focused even after this, so the cursor will keep blinking and we don't want that. As mentioned here:

http://www.java2s.com/Code/Flash-Flex-ActionScript/TextField/ToremovefocusfromatextfieldyoushouldassignStagefocusthenullvalue.htm

you should also unfocus the stage along with hiding the keyboard.

stage.unfocusAll()
\$\endgroup\$
  • \$\begingroup\$ Setting a clickable actor (in my case a dialog) does not do the trick for me. I enable touchable and print "dialog" on every click, so taht works. However it does not remove focus from my textfields \$\endgroup\$ – Green_qaue Jul 25 '15 at 21:38
  • \$\begingroup\$ Wow thanks! :) keyboardFocusChanged didn't work. But the second method did the trick. I put a big button in the background and placed the setOnscreenKeyboardVisible(false) in its listener and added the button to stage above all others. \$\endgroup\$ – WeirdElfB0y Jul 26 '15 at 6:19
  • 1
    \$\begingroup\$ Hehe, sometimes you have to think a bit out of the box ;). \$\endgroup\$ – Madmenyo Jul 26 '15 at 6:20
  • \$\begingroup\$ @iQue Are you trying to do the same thing as me?? \$\endgroup\$ – WeirdElfB0y Jul 26 '15 at 6:22
  • 1
    \$\begingroup\$ @iQue It's pretty small addition actually. Add this code at the top, before adding any other buttons: hastebin.com/otoveqelam.avrasm \$\endgroup\$ – WeirdElfB0y Jul 27 '15 at 7:05
2
\$\begingroup\$

Menno Gouw's answer is correct and is probably the way to go in most cases, but just in case someone runs into my problem where that solution might distort the positioning of other actors I thought I'd post how I solved it.

First Create an "invisible" button:

ImageButtonStyle style = new ImageButtonStyle();
style.up = null;
style.down = null;
cancelFocusButton = new ImageButton(style);

Second, add your listener to the invisible button:

cancelFocusButton.addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        Gdx.input.setOnscreenKeyboardVisible(false);
        stage.unfocusAll();
    }
});

Third, add this button to a stack together with the table that holds all your other actors (Textfields, labels, button etc):

Stack stack = new Stack();
stack.addActor(cancelFocusButton);
stack.addActor(tempTable);

Lastly add your stack to your "main table" (in my case the ContentTable inside the dialog):

getContentTable().add(stack).expand().fill();
\$\endgroup\$
1
\$\begingroup\$

I needed to do the same thing and went for an extremely simple solution in the end and it seems to work well.

I created my own StageExtension class that extends Stage (for other reasons), but within this I simply override the touchDown method adding 2 lines;

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    super.unfocusAll();
    Gdx.input.setOnscreenKeyboardVisible(false);
    return super.touchDown(screenX, screenY, pointer, button);
}

You can of course add some simple checks in there to match your needs, but this works perfectly for me.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.