Tworzenie SoftKeyboard z wieloma / alternatywnymi znakami na klucz

Podążałem za przykładami na developer.android.com dotyczące metod wprowadzania i odtwarzane za pomocą przykładowej aplikacji SoftKeyboard. Te razem dają więcej niż wystarczająco dużo informacji dotyczących tworzenia prostej klawiatury.

To czego nie widzę w API to możliwość tworzenia alternatywnych / wielu znaków na Klawisz, która jest dostępna na standardowej klawiaturze (LatinIME Keyboard).

Tutaj wpisz opis obrazka

Powyższy obrazek jest wynikiem długie naciśnięcie klawisza "a". Po długim naciśnięciu klawisza możliwe jest wypełnienie wyskakującego okienka alternatywnymi znakami.

Tutaj wpisz opis obrazka

Możliwe jest również podanie podpowiedzi popup na niektórych klawiszach, która poprosi użytkownika o naciśnięcie i przytrzymanie klawisza, aby uzyskać menu popup.

Do tej pory nie znalazłem ani jednego źródła informacji na temat tego, jak to osiągnąć, mam nadzieję, że ktoś będzie w stanie dać mi fory, do tego czasu będę podążał za kodem źródłowym wbudowanej klawiatury i może uda mi się to odtworzyć.

Edit: pomogłoby, gdyby developer.android.com 's link to LatinIME Keyboard didn' t link to a picture of a Sheep :) Actual source code for LatinIME.java .

Edit 2: bardziej jako odniesienie niż cokolwiek innego, jest to sekwencja, którą wierzę, że zwykła akcja longPress przechodzi, aby pokazać wyskakującą klawiaturę w KeyboardView.java :

onTouchEvent()
onModifiedTouchEvent()
mHandkler.handleMessage() with MSG_LONGPRESS
openPopupIfRequired() 
onLongPress()

Edit 3:

Nadal tego nie rozgryzłem-Jak dodać sugestie etykiet do kluczy? Odpowiedź sugeruje, że nie jest wbudowany w API i rzeczywiście nie znalazłem kodu, aby to zrobić. Jednak Klawiatura w wersji 2.3.4 (API 10) pokazuje, że ta funkcjonalność jest implementowana:

Tutaj wpisz opis obrazka

Bardzo chciałbym dowiedzieć się, jak to robi, ale nie ma go nigdzie w metodzie onDraw(), którą widzę - co sprawia, że wierzę, że jest napisany poza elementem KeyboardView. Nie mogę. jednak znajdź plik layout używany do wyświetlania elementu KeyboardView na wbudowanej klawiaturze - jeśli ktoś wie, gdzie to znaleźć, może to da mi wskazówkę, której potrzebuję.

Edit 4: przeniesione pytanie podglądu klawisza tutaj, ponieważ jest nieco poza tematem:

Jak wyłączyć okno podglądu klucza SoftKeyboard?

Author: Graeme, 2011-10-13

6 answers

Implementacja alternatywnego klucza popup:

Dla każdego klawisza, który chcesz mieć klawiaturę popup należy zdefiniować popupCharacters i popupKeyboard :

/res/xml/[Keyboard].xml

<Key android:keyLabel="("
    android:popupKeyboard="@xml/keyboard_popup_template"
    android:popupCharacters="[{&lt;" />

{[6] } jest reprezentacją XML klawiatury używanej w popupie zawierającym alternatywne klawisze:

/res/xml/keyboard_popup_template.xml

<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="10%p"
    android:horizontalGap="0px"
    android:verticalGap="0px"
    android:keyHeight="56dp">
</Keyboard>

Styling the alternate key popup:

Jeśli chcesz zmienić układ / styl wyskakującego okienka (który domyślnie @android: layout / keyboard_popup_keyboard.xml) możesz określić atrybut android:popupLayout, który wskazuje na plik układu:

<android.inputmethodservice.KeyboardView
    android:id="@+id/keyboard"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:background="#FF272727"
    android:popupLayout="@layout/keyboard_popup_keyboard" />

Implementacja Nakładki Podglądu Klucza:

Jedynym rozwiązaniem, które udało mi się zebrać, aby pokazać podgląd klawiszy (bez całkowicie przepisywania kodu źródłowego Keyardview) jest poniżej:

Owijanie znacznika <KeyboardView> znacznikiem <FrameLayout> o wysokości określonej przez pomnożenie klucza przez ilość wierszy. Wewnątrz tego tagu mam po prostu tworzymy LinearLayout do przechowywania wierszy, a następnie LinearLayout dla każdego wiersza zawierającego widok tekstu o wadze równej wartości % p określonej dla każdego <Key>:

<TextView android:text="!" style="@style/Custom.Widget.KeyboardKeyOverlay"  android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="10"/>

I stylizowane:

<style name="CustomTheme.Widget.KeyboardKeyOverlay">
    <item name="android:background">@android:color/transparent</item>
    <item name="android:textColor">#FFAAAAAA</item>
    <item name="android:paddingRight">6dp</item>
    <item name="android:paddingTop">4dp</item>
    <item name="android:textSize">10sp</item>
    <item name="android:gravity">right</item>
    <item name="android:textStyle">bold</item>
</style>         

Co daje:

Tutaj wpisz opis obrazka

Nie będę szczęśliwy, dopóki nie uda mi się zaimplementować tego w taki sam sposób, jak robi to klawiatura systemowa!

 50
Author: Graeme,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-14 09:24:45

Sądząc po mojej własnej próbie kodowania softkeyboard dowiedziałem się, że: {]}

  • funkcje Nice / bling zwykle wymagają rozszerzenia {[3] } i zasadniczo napisania dużych części kodu rysowania. Niestety nie można tego zrobić, nadpisując niektóre kluczowe metody, ponieważ prawie wszystko jest prywatne. Może warto zajrzeć (i pożyczyć jakiś kod od:
    • (base)/core/java/android/inputmethodservice/KeyboardView.java (android core code repo)
    • (apps)/other/LatinIME/LatinKeyboardView.java (Android Core apps repo)

Zauważ, że Owce na android.kernel.org czy istnieje, aby powiedzieć, że repo jest zamknięty z powodu krakersy, ale istnieją lustrzanki kodu gdzie indziej (zgubiłem linki niestety)

  • baza KeyboardView posiada brak wsparcie dla shadowed key hints, musisz zakodować swój własny KeyboardView, aby mieć możliwość nadpisania metody onDraw ().

Teraz na co można zrobić:

  • Możesz obejście tego problemu poprzez podanie obrazów dla kluczy: użyj xml <Key ... android:keyIcon="@drawable/this_key_icon_file /> w tym celu. Niestety, na pewno będziesz miał słabe wyniki dla listów z tą metodą(problemy z rozwiązywaniem).

  • Możesz użyć (i skonfigurować wygląd) wyskakującej klawiatury, która pojawia się po długim naciśnięciu.

Zadeklaruj szablon Klawiatury res/xml/kbd_popup_template.xml:

<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="10%p"
    android:horizontalGap="0px"
    android:verticalGap="0px"
    android:keyHeight="@dimen/key_height">
</Keyboard>

Zadeklaruj wartości łańcuchowe zawierające klawisze, które chcesz na tej klawiaturze res/values/strings.xml:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string name="alternates_for_a">àáâãäåæ</string>
</ressources>

Następnie użyj obu w swoim definicja układu klawiatury:

<Key android:codes="97" android:keyLabel="a"  
    android:popupKeyboard="@xml/kbd_popup_template"
    android:popupCharacters="@string/alternates_for_a" />
  • Można również użyć double-tap, triple-tap, ... funkcja generowania alternatyw dla klawisza, którego dotykasz. Aby to zrobić, wystarczy użyć listy dla kodów klawiszy Androida:

    <Key android:codes="97,224,230" .../>

Wyprodukuje 97= 'a ' dla pojedynczego kranu, 224='à' dla podwójnego stuknięcia i 230= "æ " dla potrójnego stuknięcia.

Czas trwania do rozważenia podwójnego stukania jest ustawiony na 800ms w kodzie źródłowym Androida. To niestety hardcoded (i trochę wysoki, czuję).

Należy pamiętać, że podczas podwójnego stukania wysyła najpierw " a", a następnie, po drugim stuknięciu wysyła " à". Niektóre aplikacje, nie spodoba się to.

 14
Author: Laurent',
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-14 14:04:10

Ta wyskakująca Klawiatura z przyciskiem zamknij jest irytująca, gdy mamy tylko jeden wyskakujący znak. Prostszym sposobem jest nadpisanie metody onLongPress takiej klasy KeyboardView.

@Override
protected boolean onLongPress(Key key) {
    if (key.codes[0] == '1') {
        getOnKeyboardActionListener().onKey('!', null);
        return true;
    }
}
 12
Author: Ganindu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-21 12:54:46

Jeśli chcesz mieć tekst na górze klawisza, możesz to zrobić w metodzie onDraw () w swojej klasie, która nadpisuje KeyboardView

 @Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    ...
    Paint paint = new Paint();
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setTextSize(18);
    paint.setColor(Color.WHITE);
    //get all your keys and draw whatever you want
    List <Keyboard.Key> keys = getKeyboard().getKeys();
    for(Keyboard.Key key: keys) {
        if(key.label != null) {

            if (key.label.toString().equals("q") || key.label.toString().equals("Q"))
                canvas.drawText(String.valueOf(1), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("w") || key.label.toString().equals("W"))
                canvas.drawText(String.valueOf(2), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("e") || key.label.toString().equals("E"))
                canvas.drawText(String.valueOf(3), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("r") || key.label.toString().equals("R"))
                canvas.drawText(String.valueOf(4), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("t") || key.label.toString().equals("T"))
                canvas.drawText(String.valueOf(5), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("y") || key.label.toString().equals("Y"))
                canvas.drawText(String.valueOf(6), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("u") || key.label.toString().equals("U"))
                canvas.drawText(String.valueOf(7), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("i") || key.label.toString().equals("I"))
                canvas.drawText(String.valueOf(8), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("o") || key.label.toString().equals("o"))
                canvas.drawText(String.valueOf(9), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("p") || key.label.toString().equals("P"))
                canvas.drawText(String.valueOf(0), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else
            {}
        }
    }
}
 7
Author: Fedor Tsyganov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-31 23:57:30

Dla każdego, kto próbuje odrzucić wyskakującą klawiaturę, stukając poza jej obszarem widoku, miałem szczęście umieścić TouchListener na KeyboardView wewnątrz klasy rozszerzającej InputMethodService

public class YourIME extends InputMethodService{
    @Override 
    public View onCreateInputView() {
        mInputView = (LatinKeyboardView) getLayoutInflater().inflate(R.layout.input, null);
        setLatinKeyboard(mQwertyKeyboard);

        mInputView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {

                if(motionEvent.getAction() == MotionEvent.ACTION_DOWN) {                        
                    mInputView.closing(); // Close popup keyboard if it's showing
                }
                return false;
            }
        });

        return mInputView;
    }
// The rest of your ime ...
}
 5
Author: Sammy T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-24 10:27:23

Jeśli chcesz mieć tekst na klawiszu, możesz to zrobić w metodzie onDraw() w twojej klasie, która rozszerza KeyboardView zrobiłem coś takiego może to komuś pomoże

Tutaj wpisz opis obrazka

 @Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Log.d("LatinKeyboardView", "onDraw");

    Paint paint = new Paint();
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setTextSize(30);
    paint.setColor(Color.LTGRAY);

    List<Key> keys = getKeyboard().getKeys();
    for (Key key : keys) {
        if (key.label != null) {
            switch (key.codes[0]) {

                //qQ
                case 81:
                case 113:
                case 1602:
                case 1618:
                    canvas.drawText(String.valueOf(1), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //wW
                case 87:
                case 119:
                case 1608:
                case 1572:
                    canvas.drawText(String.valueOf(2), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //eE
                case 69:
                case 101:
                case 1593:
                case 1617:
                    canvas.drawText(String.valueOf(3), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


                //rR
                case 82:
                case 114:
                case 1585:
                case 1681:
                    canvas.drawText(String.valueOf(4), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //tT
                case 84:
                case 116:
                case 1578:
                case 1657:
                    canvas.drawText(String.valueOf(5), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //yY
                case 89:
                case 121:
                case 1746:
                case 1552:
                    canvas.drawText(String.valueOf(6), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //uU
                case 85:
                case 117:
                case 1569:
                case 1574:
                    canvas.drawText(String.valueOf(7), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //iI
                case 73:
                case 105:
                case 1740:
                case 1648:
                    canvas.drawText(String.valueOf(8), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //oO
                case 79:
                case 111:
                case 1729:
                case 1731:
                    canvas.drawText(String.valueOf(9), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //pP
                case 80:
                case 112:
                case 1662:
                case 1615:
                    canvas.drawText(String.valueOf(0), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


                //aA
                case 65:
                case 97:
                case 1575:
                case 1570:
                    canvas.drawText("@", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //sS
                case 83:
                case 115:
                case 1587:
                case 1589:
                    canvas.drawText("#", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //dD
                case 68:
                case 100:
                case 1583:
                case 1672:
                    canvas.drawText("$", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //fF
                case 70:
                case 102:
                case 1601:
                case 1613:
                    canvas.drawText("%", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //gG
                case 71:
                case 103:
                case 1711:
                case 1594:
                    canvas.drawText("&", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //hH
                case 72:
                case 104:
                case 1726:
                case 1581:
                    canvas.drawText("-", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //jJ
                case 74:
                case 106:
                case 1580:
                case 1590:
                    canvas.drawText("+", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //kK
                case 75:
                case 107:
                case 1705:
                case 1582:
                    canvas.drawText("(", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //lL
                case 76:
                case 108:
                case 1604:
                case 1614:
                    canvas.drawText(")", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //zZ
                case 90:
                case 122:
                case 1586:
                case 1584:
                    canvas.drawText("*", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //xX
                case 88:
                case 120:
                case 1588:
                case 1679:
                    canvas.drawText("\"", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //cC
                case 67:
                case 99:
                case 1670:
                case 1579:
                    canvas.drawText("\'", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //vV
                case 86:
                case 118:
                case 1591:
                case 1592:
                    canvas.drawText(":", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //bB
                case 66:
                case 98:
                case 1576:
                case 1616:
                    canvas.drawText(";", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //nN
                case 78:
                case 110:
                case 1606:
                case 1722:
                    canvas.drawText("!", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //mM
                case 77:
                case 109:
                case 1605:
                case 1611:
                    canvas.drawText("?", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


            }

        }

    }
}

Dostosuj te oś według własnego wyboru

int keyXAxis = 25;
int keyYAxis = 50;
 0
Author: Mateen Chaudhry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-23 09:38:10