When writing in the Textfield, I need my textfield to move upwards in order to let the textfield be visible when the keyboard pops up.
Does libgdx have some kind of method which returns true if the keyboard is visible and false when it is down?
The following code will detect when you press a textfield, prevent it from showing the keyboard and then open a native dialog that moves up and down with the keyboard. It will take the input from the native dialog and finally put it back in your textField:
textField.setOnscreenKeyboard(new TextField.OnscreenKeyboard() {
@Override
public void show(boolean visible) {
//Gdx.input.setOnscreenKeyboardVisible(true);
Gdx.input.getTextInput(new Input.TextInputListener() {
@Override
public void input(String text) {
textField.setText(text);
}
@Override
public void canceled() {
System.out.println("Cancelled.");
}
}, "Title", "Default text...");
}
});
Good Luck!
I know I'm answering to an old thread, but I was googling to find an answer to this question but couldn't find it anywhere. Now I have created a solution myself. Here is how to do it on Android in an elegant way :) I'm creating an ApplicationBundle to bundle interfaces to add platform specific things. You can do this on iOS too if you want to make use of RoboVM.
My solution:
create a SizeChangeListener interface in the core project:
public interface SizeChangeListener {
public void onSizeChange(float width, float height);
}
create a View interface in the core project:
public interface View {
public void onSizeChange(float width, float height);
public void addListener(SizeChangeListener sizeChangeListener);
public float getWidth();
public float getHeight();
}
create an AndroidView implementing the View interface:
public class AndroidView implements View {
private ArrayList<SizeChangeListener> listeners = new ArrayList<SizeChangeListener>();
private float width, height;
public AndroidView(int width, int height) {
this.width = width;
this.height = height;
}
public void addListener(SizeChangeListener listener) {
listeners.add(listener);
}
public void onSizeChange(float width, float height) {
this.width = width;
this.height = height;
for(SizeChangeListener listener : listeners)
listener.onSizeChange(width, height);
}
public float getWidth() {
return width;
}
public float getHeight() {
return height;
}
}
create an ApplicationBundle in the core project
public class ApplicationBundle {
private final View view;
public ApplicationBundle(View view) {
this.view = view;
}
public View getView() {
return view;
}
}
Make the necessary imports from the core project. In the AndroidLauncher in the Android project add the following:
public class AndroidLauncher extends AndroidApplication {
private View rootView;
private AndroidView androidView;
private int width, height;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
rootView = this.getWindow().getDecorView().getRootView();
Rect rect = new Rect();
rootView.getWindowVisibleDisplayFrame(rect);
width = rect.width();
height = rect.height();
androidView = new AndroidView(width, height);
rootView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
Rect rect = new Rect();
rootView.getWindowVisibleDisplayFrame(rect);
if(!(width == rect.width() && height == rect.height())) {
width = rect.width();
height = rect.height();
androidView.onSizeChange(width, height);
}
}
});
initialize(new DigMeApp(new ApplicationBundle(androidView)), config);
}
}
In your main MyApp in the core project in the create() method add a SizeChangeListener implementation to the view you've got from the constructor.
public class MyApp extends Game { // or ApplicationAdapter
private View view;
private Stage stage;
// your own variables
public MyApp(ApplicationBundle applicationBundle) {
view = applicationBundle.getView();
}
@Override
public void create () {
stage = new Stage();
// add some textfields
final TextField tf1 = new TextField("", skin);
final TextField tf2 = new TextField("", skin);
tf1.setWidth((float)view.getWidth() * 0.6f);
tf2.setWidth((float)view.getWidth() * 0.6f);
tf1.setHeight((float)view.getHeight() * 0.05f);
tf2.setHeight((float)view.getHeight() * 0.05f);
view.addListener(new SizeChangeListener() {
@Override
public void onSizeChange(float width, float height) {
Gdx.app.log("INFO", "Visible area: " + width + " " + height);
Gdx.app.log("INFO", "Stage area: " + stage.getWidth() + " " + stage.getHeight());
float keyboardHeight = getKeyboardHeight();
// MOVE THEM OUT OF THE WAY :)
tf1.addAction(Actions.moveTo(width / 2 - tf1.getWidth() / 2.0f, keyboardHeight + (6 * (height / 8)), 1, Interpolation.sineOut));
tf2.addAction(Actions.moveTo(width / 2 - tf2.getWidth() / 2.0f, keyboardHeight + (7 * (height / 8)), 1, Interpolation.sineOut));
// Gdx.gl20.
// tf.setPosition(width / 2 - (tf.getWidth() / 2.0f), 0);
}
});
}
Perhaps create a little keyboard heigt method like I did:
private float getKeyboardHeight() {
return stage.getHeight() - view.getHeight();
}
Try
Gdx.input.isPeripheralAvailable(Input.Peripheral.OnscreenKeyboard);
I just looked this up in the docs, don't know if it actually does the trick. But the
Gdx.input.setOnscreenKeyboardVisible(boolean visible);
method could be used as well (like this YOU define when the keyboard is visible and when not).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With