2012-03-07 16 views
7

Cuando escribo en el campo de texto, necesito que mi campo de texto se mueva hacia arriba para que el campo de texto esté visible cuando aparece el teclado.Cómo detecta libgdx la presencia del teclado

¿Tiene libgdx algún tipo de método que devuelve verdadero si el teclado es visible y falso cuando está inactivo?

+0

posible duplicado de [Detectar si el teclado blando es visible en la pantalla] (http://stackoverflow.com/questions/4745988/ detect-if-soft-keyboard-is-visible-on-screen) –

+0

Esto no tiene nada que ver con libgdx, quiere escuchar un evento Android nativo.Esta pregunta se ha realizado y respondido –

+3

Un poco, pero si no lo proporciona LibGDX, el esfuerzo de implementación para escuchar este evento es mucho más grande;). – dom

Respuesta

1

Trate

Gdx.input.isPeripheralAvailable(Input.Peripheral.OnscreenKeyboard); 

Acabo de ver esto en la documentación, no sé si lo que realmente hace el truco. Pero el método

Gdx.input.setOnscreenKeyboardVisible(boolean visible); 

podría utilizarse también (como esta usted define cuando el teclado es visible y cuando no).

+0

Han intentado Input.Peripheral.OnscreenKeyboard, pero siempre es así cuando se ejecuta la aplicación en android. Pero intentaré hacerlo manualmente, gracias por la sugerencia :) –

+1

De lo contrario, como sugirió Andrei Bodnarescu, siempre puedes escuchar los eventos como se describe en http://stackoverflow.com/questions/4745988/detect-if-soft -keyboard-is-visible-on-screen, use la misma estructura que describí en http://stackoverflow.com/questions/9584959/using-sqlite-from-libgdx-on-android/9590715#9590715. ¡Aclamaciones! – dom

+0

Parece regresar siempre cierto, ¿no? – JohnyTex

12

El siguiente código detectará cuando presiona un campo de texto, evita que se muestre el teclado y luego abre un diálogo nativo que se mueve hacia arriba y hacia abajo con el teclado. Se llevará a la entrada desde el diálogo nativa y, finalmente, poner de nuevo en su 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..."); 
     } 
    }); 

buena suerte!

+1

¿Alguna idea de cómo cambiamos el estilo de este diálogo nativo? –

+1

No. Supongo que no puede hacer eso porque diferirá entre Android y iPhone y el escritorio de Java, etc. En resumen: su nativo => ¡Funciona de forma nativa! – JohnyTex

+0

Genial, gracias por esa respuesta! – middlehut

7

Sé que estoy respondiendo a un hilo antiguo, pero estaba buscando en Google para encontrar una respuesta a esta pregunta, pero no pude encontrarla en ningún lado. Ahora he creado una solución yo mismo. Aquí está cómo hacerlo en Android de una manera elegante :) Estoy creando un ApplicationBundle para agrupar interfaces para agregar cosas específicas de la plataforma. También puedes hacer esto en iOS si quieres hacer uso de RoboVM.

Mi solución:

crear una interfaz SizeChangeListener en el proyecto central:

public interface SizeChangeListener { 
    public void onSizeChange(float width, float height); 
} 

crear una interfaz de Vista en el proyecto central:

public interface View { 
    public void onSizeChange(float width, float height); 
    public void addListener(SizeChangeListener sizeChangeListener); 
    public float getWidth(); 
    public float getHeight(); 
} 

crear una AndroidView implementación de la interfaz Vista :

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; 
    } 

} 

crear un ApplicationBundle en el proyecto central

public class ApplicationBundle { 

    private final View view; 

    public ApplicationBundle(View view) { 
     this.view = view; 
    } 

    public View getView() { 
     return view; 
    } 
} 

Hacer las importaciones necesarias del proyecto central. En el AndroidLauncher en el proyecto Android agregar lo siguiente:

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); 
    } 
} 

en su MiApl principal en el proyecto básico del método create() añadir una aplicación SizeChangeListener a la vista que tienes desde el 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); 
      } 
     }); 
} 

Tal vez crear un método poco heigt teclado como lo hice:

private float getKeyboardHeight() { 
     return stage.getHeight() - view.getHeight(); 
    } 
+0

Me encanta esta respuesta, funciona muy bien en todos los dispositivos en los que lo he probado. El único comentario que haría es 'view.getHeight()' debe escalarse para coincidir con las dimensiones de la etapa o la cámara si ha forzado a libgdx a ser una resolución particular. @Willempie ¿tienes una solución funcional para iOS? – hamham

+0

Esta es una gran respuesta, funciona muy bien, y afortunadamente no tengo que implementar el modo iOS, así que eso no es un problema. Esta debería ser la respuesta seleccionada, aunque tengo una advertencia. Cuando toco un campo de texto, cuando aparece el teclado, también aparece un cartel negro en la parte superior de mi aplicación con el nombre de mi aplicación. Parece estar en la línea 'rootView = this.getWindow(). GetDecorView(). GetRootView();' ¿Alguna idea de cómo evitar esto? –

+0

[SOLUCIONADO] 'this.requestWindowFeature (Window.FEATURE_NO_TITLE);' Agregué esta línea antes de que rootView se establezca –

Cuestiones relacionadas