2012-12-21 11 views
31

Chciałbym zrobić zakrzywioną klawiaturę ekranową dla Androida. Przeanalizowałem softkeyboard i różne inne na klawiaturach ekranowych w kodzie google. Żadne, które znalazłem, nie obejmuje kształtu klawiatury, który jest niczym innym niż prostokątem. Idealnie chciałbym stworzyć klawiaturę składającą się z klawiszy rozmieszczonych w dwóch półkoliach po przeciwnych stronach ekranu (tj. Wyobraź sobie trzymanie tabletu za boki i możliwość uderzenia klawiszy kciukami).Jak zrobić zakrzywioną klawiaturę ekranową dla Androida

Z kodu, który badałem, klawisze ekranowe są tworzone jako widoki (zwykle rozszerzające KeyboardView) i pojawiają się jako ciągły pasek u dołu ekranu. Jako przybliżenie mojego celu, próbowałem zmienić kod znaleziony w kodzie google (dotdash-keyboard-android), aby narysować jego klucze w lewym dolnym rogu i pozostawić prawy dolny róg przezroczysty. Byłem w stanie nadpisać MeasureMance, aby wpłynąć na wymiary widoku (patrz poniżej), ale to tylko wydaje się zmieniać pozycje klawiszy, a nie pozycje kontenera. Innymi słowy, wciąż jest czarny pasek wypełniający dolną część ekranu.

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

Czy to, co chcę robić, nawet możliwe? Czy jest na to bardziej poprawny termin? Czy istnieją projekty, które mogę wykorzystać jako przykłady?

Próbowałem również ustawić wymiary widoku za pomocą this.setLayoutParams - ale te wywołania wydają się nie mieć wpływu. Próbowałem również użyć this.getParent, aby uzyskać dostęp do widoku nadrzędnego (jeśli taki istnieje) i zmienić jego wymiary, ale to podejście nie działa (lub, po prostu robię to źle). Każda pomoc byłaby bardzo cenna.

Dziękuję

Aktualizacja: 12/21/2012 - Myślę, że trzeba zastąpić metodę klasy nadrzędnej za OnDraw. Patrząc here, wygląda na to metoda KeyboardView za OnDraw rysuje na płótnie, które jest równa wielkości ekranu przy użyciu następującego kodu:

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

myślę, że mogę zastąpić OnDraw i wyciągnąć co chcę na płótnie.

AKTUALIZACJA: 12/21/2012 - Nadpisałem naDrawie i teraz jest jasne, że klawiatura jest wymiarami, na które ją ustawiam (200x200). Używając Hierarchyview, widzę, że widok klawiatury jest wewnątrz frarmayout z identyfikatorem InputArea. Tak więc poziomy pasek, który wypełnia całą szerokość, jest tym framelayout. Ale nie tworzę tego - skąd się bierze i jak mogę zmienić jego wymiary?

AKTUALIZACJA: 12/22/2012 - Po kolejnych testach wydaje się, że zachowanie (wymiary) widoku klawiatury są częściowo określone przez działanie, które je wywołuje. W przeglądarce uzyskuję opisywane przeze mnie zachowanie: wysokość okna przeglądarki zmniejsza się, aby pomieścić pasek u dołu ekranu, na którym znajduje się klawiatura, nawet jeśli szerokość klawiatury jest mniejsza niż szerokość ekran. W aplikacji kalendarza rozmiar klawiatury pojawia się tak, jak go ustawiłem (jako kwadrat w lewym dolnym rogu), a pod nim pojawia się niezmieniony kalendarz. Tak więc osiągnięcie większości celów przy użyciu tego podejścia wydaje się niemożliwe. Alternatywne podejście może polegać na tym, aby usługa IME tworzyła okno dialogowe lub okno dialogowe. Jednym z problemów jest to, że okna popupwindows potrzebują widoku lub kotwicy nadrzędnej do przyłączenia się i nie sądzę, że można znaleźć najwyższy widok z usługi IME. Być może mogę stworzyć przejrzysty widok na bieżącą aktywność i umieścić na niej okienko wyskakujące?

AKTUALIZACJA: 12/23/2012 - Postęp. Wymyśliłem, jak wyświetlić wyskakujące okienko z klawiatury IME. Następnym krokiem jest dowiedzieć się, jak zrobić wyskakujące okienka trochę zaokrąglone/ekologiczne. Oto zrzut ekranu z tego, co osiągnąłem, a następnie źródło. Emulator screenshot of keyboard

Źródło. Następująca metoda znajduje się w klasie IME usługi i wywoływana przez metodę onMeasure widoku podrzędnego (usługi), dzięki czemu wyskakujące okienka otwierają się w tym samym czasie, gdy zostanie narysowana klawiatura. Ustawiłem wymiary klawiatury na 1x1, więc nie jest widoczne. Logi mają pomóc mi dowiedzieć się, jak pozycjonować wyskakujące okienka.

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

sprawdź ten link. [używając zakrzywionego kształtu] (http://stackoverflow.com/a/10140513/793943). – Sush

+1

ciekawe pytanie - pójdę za nim pod kątem możliwych odpowiedzi .... niestety nie mam nic do dodania, aby ci pomóc. –

Odpowiedz

1

Wygląda na to, że jesteś na dobrej drodze. Jak już zauważyłeś, większość działań zmniejszy ich widoki, aby zapewnić miejsce na okno klawiatury, więc jeśli chcesz, aby aktywność wywołująca wypełniała ekran, musisz użyć dodatkowego okna, takiego jak PopupWindow. Możesz ustawić wymiary głównego okna na 0x0.

Czy próbowałeś dzwonić pod numer popUpLeft.setBackgroundDrawable(null)/? To powinno usunąć półprzezroczyste tło i pokazać tylko to, co rysujesz na wierzchu.

Powiązane problemy