android - google - teclado para celular tactil
Cómo hacer un teclado curvo en pantalla para Android (1)
Me gustaría hacer un teclado curvo en pantalla para Android. He examinado el softkeyboard, y varios otros teclados en pantalla en el código de Google. Ninguno de los que he encontrado tiene que ver con una forma de teclado que no sea un rectángulo. Idealmente, me gustaría crear un teclado que consiste en teclas distribuidas en dos semicírculos en lados opuestos de la pantalla (es decir, imagina sostener una tableta por los lados y poder presionar las teclas con tus pulgares).
Del código que he examinado, los teclados en pantalla se crean como vistas (generalmente extendiendo KeyboardView) y aparecen como una barra continua en la parte inferior de la pantalla. Como una aproximación a mi objetivo, he intentado alterar el código que encontré en el código de google (dotdash-keyboard-android) para dibujar solo sus teclas en la esquina inferior izquierda y dejar la esquina inferior derecha transparente. He podido anular onMeasure para afectar las dimensiones de la vista (ver más abajo), pero esto solo parece alterar las posiciones de las teclas y no las posiciones del contenedor. En otras palabras, todavía hay una barra negra que llena la parte inferior de la pantalla.
//Located within KeyboardView
@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
this.setMeasuredDimension(200, 200);
}
¿Es lo que quiero hacer posible? ¿Hay un término más correcto para esto? ¿Hay proyectos que pueda usar como ejemplos?
También he intentado establecer las dimensiones de la vista usando this.setLayoutParams, pero estas llamadas parecen no tener ningún efecto. También he intentado usar this.getParent para acceder a la vista principal (si existe alguna) y cambiar sus dimensiones, pero este enfoque no funciona (o lo estoy haciendo mal). Cualquier ayuda sería muy apreciada.
Gracias
ACTUALIZACIÓN: 12/21/2012 - Creo que necesito anular el método onDraw de la clase principal. Mirando here , parece que el método onDraw de KeyboardView se dibuja en un lienzo que es igual al tamaño de la pantalla usando el siguiente código:
final int width = Math.max(1, getWidth());
final int height = Math.max(1, getHeight());
mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBuffer);
Creo que puedo anular onDraw y dibujar lo que quiera en el lienzo.
ACTUALIZACIÓN: 12/21/2012 - He anulado onDraw y ahora está claro que keyboardView es las dimensiones a las que lo estoy configurando (200x200). Al usar Hierarchyview, puedo ver que la vista del teclado está dentro de un framelayout con el id InputArea. Entonces, la barra horizontal que llena todo el ancho es esta framelayout. Pero, no lo estoy creando, ¿de dónde viene y cómo puedo alterar sus dimensiones?
ACTUALIZACIÓN: 22/12/2012 - Después de más pruebas, parece que el comportamiento (dimensiones) de una vista de teclado está determinado en parte por la actividad que lo llama. En el navegador, obtengo el comportamiento que he estado describiendo: la altura de la ventana del navegador se reduce para acomodar una barra en la parte inferior de la pantalla que sostiene el teclado, incluso si el ancho del teclado es menor que el ancho del pantalla. En la aplicación de calendario, el tamaño del teclado aparece tal como lo configuré (como un cuadrado en la esquina inferior izquierda) con el calendario sin cambios debajo. Por lo tanto, parece imposible alcanzar mi objetivo con la mayoría de las aplicaciones que utilizan este enfoque. Un enfoque alternativo podría ser que el servicio IME cree una ventana emergente o un cuadro de diálogo. Un problema es que las ventanas emergentes necesitan una vista principal o un ancla para adjuntar y no creo que sea posible encontrar la vista superior desde el servicio IME. ¿Tal vez pueda crear una vista transparente sobre la actividad actual y colocar la ventana emergente encima de eso?
ACTUALIZACIÓN: 12/23/2012 - Progreso. He descubierto cómo mostrar una ventana emergente desde el teclado IME. El siguiente paso es descubrir cómo hacer que las ventanas emergentes sean un poco redondas / orgánicas. Aquí hay una captura de pantalla de lo que logré seguido por la fuente.
Fuente. El siguiente método está en la clase IME del servicio y es invocado por el método onMeasure de la vista secundaria (del servicio) para que se abran las ventanas emergentes al mismo tiempo que se dibuja el teclado. Establecí las dimensiones del teclado en 1x1 para que no sea visible. Las instrucciones de registro están ahí para ayudarme a descubrir cómo colocar las ventanas emergentes.
public void initiatePopupWindow()
{
try {
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
//display.getSize(p);
Log.i("dotdashkeyboard","initiatePopupWindow (from IME service)");
LayoutInflater inflater = (LayoutInflater) this.getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layoutLeft = inflater.inflate(R.layout.popup_layout_left,null);
View layoutRight = inflater.inflate(R.layout.popup_layout_right, null);
// create a 300px width and 470px height PopupWindow
int popupHeight = 300;
int popupWidth = 200;
if (popUpLeft == null) popUpLeft = new PopupWindow(layoutLeft, popupWidth, popupHeight, false);
if (popUpRight == null) popUpRight = new PopupWindow(layoutRight, popupWidth, popupHeight, false);
int ypos = 0;
int xposRight = 0;
if (display.getRotation() == Surface.ROTATION_0) {
ypos = -(dm.heightPixels / 2 + popupHeight/2);
xposRight = (dm.widthPixels - popupWidth);
Log.i("dotdashkeyboard","test rotation=normal");
} else if (display.getRotation() == Surface.ROTATION_90) {
ypos = -(dm.heightPixels / 2 + popupHeight/2)/2;
xposRight = (dm.widthPixels - popupWidth)*2-popupWidth;
Log.i("dotdashkeyboard","test rotation=90-degrees");
} else {
Log.i("dotdashkeyboard","test rotation=unknown=" + display.getRotation());
}
popUpLeft.showAtLocation(inputView, Gravity.NO_GRAVITY, 0, ypos);
popUpRight.showAtLocation(inputView, Gravity.NO_GRAVITY, xposRight, ypos);
Log.i("dotdashkeyboard","test created popup at ypos="+ypos + " xposRight=" + xposRight);
Log.i("dotdashkeyboard","test screenWidth=" + dm.widthPixels + " screenHeight=" + dm.heightPixels);
Button cancelButton = (Button) layoutLeft.findViewById(R.id.popup_cancel_button);
//cancelButton.setOnClickListener(inputView.cancel_button_click_listener);
cancelButton.setOnClickListener(cancel_button_click_listener);
} catch (Exception e) {
e.printStackTrace();
}
}
Pareces estar en el camino correcto aquí. Como ha notado, la mayoría de las actividades reducirán sus vistas para proporcionar espacio para la ventana del teclado, de modo que si desea que la actividad de llamada llene la pantalla, debe usar una ventana secundaria, como una ventana emergente. Puede establecer las dimensiones de su ventana principal en 0x0.
¿Ha intentado llamar a popUpLeft.setBackgroundDrawable(null)
/ popUpRight.setBackgroundDrawable(null)
? Esto debería eliminar el fondo semitransparente y mostrar solo lo que dibuje en la parte superior.