4
\$\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\$
2
  • \$\begingroup\$ Did you try to add FocusListener to an input text field? \$\endgroup\$
    – jantobola
    Jul 24, 2015 at 12:25
  • \$\begingroup\$ I tried that but it's not working. May be I used it wrong: hastebin.com/poravupoto.java \$\endgroup\$
    – Neerkoli
    Jul 25, 2015 at 11:04

3 Answers 3

4
\$\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\$
16
  • \$\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, 2015 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\$
    – Neerkoli
    Jul 26, 2015 at 6:19
  • 1
    \$\begingroup\$ Hehe, sometimes you have to think a bit out of the box ;). \$\endgroup\$
    – Madmenyo
    Jul 26, 2015 at 6:20
  • \$\begingroup\$ @iQue Are you trying to do the same thing as me?? \$\endgroup\$
    – Neerkoli
    Jul 26, 2015 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\$
    – Neerkoli
    Jul 27, 2015 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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .