How do libgdx detect keyboard presence

后端 未结 3 1345
盖世英雄少女心
盖世英雄少女心 2020-12-10 05:29

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

相关标签:
3条回答
  • 2020-12-10 05:54

    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!

    0 讨论(0)
  • 2020-12-10 05:56

    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();
        }
    
    0 讨论(0)
  • 2020-12-10 06:00

    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).

    0 讨论(0)
提交回复
热议问题