2012-12-21 16 views
31

Mi piacerebbe creare una tastiera su schermo curva per Android. Ho esaminato la tastiera e vari altri su tastiere su google. Nessuno che ho trovato coinvolge una forma di tastiera che è qualcosa di diverso da un rettangolo. Idealmente, mi piacerebbe creare una tastiera composta da tasti distribuiti su due semicerchi sui lati opposti dello schermo (ad esempio, immagina di tenere una tavoletta ai lati e di poter colpire i tasti con i pollici).Come realizzare una tastiera a schermo curvo per Android

Del codice che ho esaminato, le tastiere su schermo vengono create come viste (di solito estendendo KeyboardView) e appaiono come una barra continua nella parte inferiore dello schermo. Come approssimazione al mio obiettivo, ho provato ad alterare il codice che ho trovato su google code (dotdash-keyboard-android) per disegnare solo le sue chiavi nell'angolo in basso a sinistra e lasciare l'angolo in basso a destra trasparente. Sono stato in grado di sovrascrivere su Misura per influenzare le dimensioni della vista (vedi sotto), ma questo sembra solo alterare le posizioni dei tasti e non le posizioni del contenitore. In altre parole, c'è ancora una barra nera che riempie la parte inferiore dello schermo.

//Located within KeyboardView 
@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ 
    this.setMeasuredDimension(200, 200); 
} 

È quello che voglio fare anche possibile? C'è un termine più corretto per questo? Ci sono progetti che posso usare come esempi?

Ho anche provato a impostare le dimensioni della vista utilizzando this.setLayoutParams - ma, queste chiamate sembrano non avere alcun effetto. Ho anche provato a usare this.getParent per accedere alla vista genitore (se ne esiste addirittura una) e cambiarne le dimensioni, ma questo approccio non funziona (o, semplicemente, sto sbagliando). Qualsiasi aiuto sarebbe molto apprezzato.

Grazie

UPDATE: 2012/12/21 - Penso di aver bisogno di ignorare il metodo OnDraw della classe genitore. Guardando here, sembra che il metodo OnDraw di KeyboardView disegna una tela che è uguale alla dimensione dello schermo utilizzando il seguente codice:

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

penso di poter ignorare OnDraw e disegnare quello che voglio sulla tela.

AGGIORNAMENTO: 21/12/2012 - Ho sovrascritto suDraw ed è ora chiaro che la tastieraView è la dimensione in cui la sto impostando (200x200). Usando Hierarchyview, posso vedere che la tastiera è all'interno di un framelayout con id InputArea. Quindi, la barra orizzontale che riempie l'intera larghezza è questo framelayout. Ma non lo sto creando - da dove viene e come posso modificare le sue dimensioni?

AGGIORNAMENTO: 22/12/2012 - Dopo ulteriori test, sembra che il comportamento (dimensioni) di una vista tastiera sia in parte determinato dall'attività che lo chiama. Nel browser, ottengo il comportamento che ho descritto: l'altezza della finestra del browser si restringe per accogliere una barra nella parte inferiore dello schermo che contiene la tastiera, anche se la larghezza della tastiera è inferiore alla larghezza del schermo. Nell'app del calendario, la dimensione della tastiera appare come l'ho impostata (come un quadrato nell'angolo in basso a sinistra) con il calendario che appare invariato sotto di esso. Pertanto, sembra impossibile raggiungere il mio obiettivo con la maggior parte delle app che utilizzano questo approccio. Un approccio alternativo potrebbe essere quello di fare in modo che il servizio IME crei una finestra popup o una finestra di dialogo. Un problema è che le finestre popup hanno bisogno di una vista genitore o ancora da collegare e non penso sia possibile trovare la vista più in alto dal servizio IME. Forse posso creare una vista trasparente sull'attività corrente e posizionare il popup sopra a quello?

AGGIORNAMENTO: 23/12/2012 - Stato avanzamento. Ho capito come visualizzare un popup dall'IME della tastiera. Il prossimo passo è capire come rendere i popup un po 'rotondo/organico. Ecco uno screenshot di ciò che ho realizzato seguito dalla fonte. Emulator screenshot of keyboard

Fonte. Il metodo seguente è nella classe IME del servizio e chiamato dal metodo onMeasure della vista child (of the service) in modo che i popup si aprano nello stesso momento in cui viene disegnata la tastiera. Ho impostato le dimensioni della tastiera su 1x1 in modo che non sia visibile. Le istruzioni del registro sono lì per aiutarmi a capire come posizionare i popup.

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(); 
    } 
} 
+2

dai un'occhiata a questo link. [utilizzando la forma curva] (http://stackoverflow.com/a/10140513/793943). – Sush

+1

domanda interessante - la seguirò per possibili risposte .... purtroppo non ho nulla da aggiungere per aiutarti. –

risposta

1

Sembra che tu sia sulla strada giusta. Come hai notato, la maggior parte delle attività ridurranno le loro viste per fornire spazio per la finestra della tastiera, quindi se vuoi che l'attività chiamante riempia lo schermo devi usare una finestra secondaria, come una finestra popup. È possibile impostare le dimensioni della finestra principale su 0x0.

Hai provato a chiamare popUpLeft.setBackgroundDrawable(null)/popUpRight.setBackgroundDrawable(null)? Questo dovrebbe rimuovere lo sfondo semitrasparente e mostrare solo ciò che si disegna sopra.

Problemi correlati