Як можна зробити власну клавіатуру в Android?


105

Я хочу зробити власну клавіатуру. Я не знаю, як це зробити за допомогою XML та Java. На наступному малюнку - модель клавіатури, яку я хочу зробити. Потрібні лише цифри.

введіть тут опис зображення


6
[Створіть власну власну клавіатуру за допомогою макетів XML для пристроїв Android] ( tutorials-android.blogspot.com/2011/06/… )
Jorgesys

1
На Tuts є хороший підручник: посилання
Хамед Гадіріан

У Google є зразок проекту "SoftKeyboard", або тут пов'язано досить багато ресурсів: customkeyboarddetails.blogspot.com/2019/02/…
oliversisson

Відповіді:


83

Перш за все вам знадобиться keyboard.xmlфайл, який буде розміщений у res/xmlпапці (якщо папки не існує, створив її).

<?xml version="1.0" encoding="utf-8"?> 
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="15%p"
    android:keyHeight="15%p" >

    <Row>
        <Key android:codes="1"    android:keyLabel="1" android:horizontalGap="4%p"/>
        <Key android:codes="2"    android:keyLabel="2" android:horizontalGap="4%p"/>
        <Key android:codes="3"    android:keyLabel="3" android:horizontalGap="4%p" />
        <Key android:codes="4"    android:keyLabel="4" android:horizontalGap="4%p" />
        <Key android:codes="5"    android:keyLabel="5" android:horizontalGap="4%p" />
    </Row>
    <Row>
        <Key android:codes="6"    android:keyLabel="6" android:horizontalGap="4%p"/>
        <Key android:codes="7"    android:keyLabel="7" android:horizontalGap="4%p"/>
        <Key android:codes="8"    android:keyLabel="8" android:horizontalGap="4%p" />
        <Key android:codes="9"    android:keyLabel="9" android:horizontalGap="4%p" />
        <Key android:codes="0"    android:keyLabel="0" android:horizontalGap="4%p" />
    </Row>

    <Row>
        <Key android:codes="-1"    android:keyIcon="@drawable/backspace" android:keyWidth="34%p" android:horizontalGap="4%p"/>
        <Key android:codes="100"    android:keyLabel="Enter" android:keyWidth="53%p" android:horizontalGap="4%p"/>
    </Row>
 </Keyboard>

** Зауважте, що вам доведеться створити backspaceфайл, що малюється, і помістити його в папку res / dravable-ldpi з дуже невеликим розміром (наприклад, 18x18 пікселів)

Потім у XML-файл, який ви хочете, щоб він використовувався (де знаходиться ваш TextView), слід додати наступний код:

<RelativeLayout
 ...
>

        .....


        <android.inputmethodservice.KeyboardView
             android:id="@+id/keyboardview"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_alignParentBottom="true"
             android:layout_centerHorizontal="true"
             android:focusable="true"
             android:focusableInTouchMode="true"
             android:visibility="gone" 
         />

        ......


</RelativeLayout>

** Зауважте, що XML-файл, у який ви розміщуєте android.inputmethodservice.KeyboardView, повинен бути таким RelativeLayout, щоб можна було встановити alignParentBottom="true"(Зазвичай клавіатури представлені внизу екрану)

Тоді вам потрібно додати наступний код у onCreateфункції того, Activityхто обробляє TextViewклавіатуру, до якої потрібно приєднати

    // Create the Keyboard
    mKeyboard= new Keyboard(this,R.xml.keyboard);

    // Lookup the KeyboardView
    mKeyboardView= (KeyboardView)findViewById(R.id.keyboardview);
    // Attach the keyboard to the view
    mKeyboardView.setKeyboard( mKeyboard );

    // Do not show the preview balloons
    //mKeyboardView.setPreviewEnabled(false);

    // Install the key handler
    mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);

** Зауважте, що mKeyboardі mKeyboardViewце приватні змінні класу, які вам потрібно створити.

Тоді вам потрібна наступна функція для відкриття клавіатури (її потрібно пов’язати з TextView через onClickвластивість xml)

    public void openKeyboard(View v)
    {
       mKeyboardView.setVisibility(View.VISIBLE);
       mKeyboardView.setEnabled(true);
       if( v!=null)((InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
    }

І нарешті вам потрібно те, OnKeyboardActionListenerщо буде обробляти ваші події

private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {
    @Override public void onKey(int primaryCode, int[] keyCodes) 
    {
         //Here check the primaryCode to see which key is pressed 
         //based on the android:codes property
         if(primaryCode==1)
         {
            Log.i("Key","You just pressed 1 button");
         }
    }

    @Override public void onPress(int arg0) {
    }

    @Override public void onRelease(int primaryCode) {
    }

    @Override public void onText(CharSequence text) {
    }

    @Override public void swipeDown() {
    }

    @Override public void swipeLeft() {
    }

    @Override public void swipeRight() {
    }

    @Override public void swipeUp() {
    }
};

Сподіваюся, що допомагає !!!

Більшість кодів знайдено тут


1
Що робити, якщо я не хочу, щоб клавіатура знаходилася внизу екрана? (наприклад, я хочу, щоб користувач міг перетягнути його навколо). Це те, що я можу контролювати за допомогою програми клавіатури чи це обробляється системою Android?
користувач3294126

ширина клавіатури не заповнює екран, що я повинен зробити, щоб він заповнив усі екрани
Джордж Томас

який батьківський макет, в якому знаходиться KeyboardView? Ви також перевірили layout_width KeyboardView ??
Pontios

1
Майте на увазі, що класи KeyboardView та Keyboard застаріли в Google з 29-го рівня API. Тому це рішення більше не працюватиме в майбутньому, якщо вам доведеться націлити новий рівень API.
maex

google застаріло. що нового рішення?
tohidmahmoudvand

78

Клавіатура системи

Ця відповідь розповідає, як зробити власну системну клавіатуру, яку можна використовувати в будь-якому додатку, встановленому користувачем на своєму телефоні. Якщо ви хочете зробити клавіатуру, яка буде використовуватися лише у вашому власному додатку, перегляньте іншу мою відповідь .

Приклад нижче буде виглядати приблизно так. Ви можете змінити його для будь-якої розкладки клавіатури.

введіть тут опис зображення

Наступні кроки показують, як створити робочу користувацьку системну клавіатуру. Якнайбільше я намагався видалити зайвий код. Якщо вам потрібні інші функції, я надав посилання на додаткову допомогу наприкінці.

1. Почніть новий проект Android

Я назвав свій проект "Спеціальна клавіатура". Назвіть це все, що завгодно. Тут немає нічого іншого особливого. Я просто покину MainActivityі "Hello World!" макет як є.

2. Додайте файли компонування

Додайте наступні два файли у папку додатка res/layout:

  • keyboard_view.xml
  • key_preview.xml

keyboard_view.xml

Цей погляд схожий на контейнер, який вміщатиме нашу клавіатуру. У цьому прикладі є лише одна клавіатура, але ви можете додати інші клавіатури та поміняти їх у та поза цим KeyboardView.

<?xml version="1.0" encoding="utf-8"?>
<android.inputmethodservice.KeyboardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:keyPreviewLayout="@layout/key_preview"
    android:layout_alignParentBottom="true">

</android.inputmethodservice.KeyboardView>

key_preview.xml

Попередній перегляд клавіш - це макет, який з’являється при натисканні клавіші клавіатури. Він просто показує, яку клавішу ви натискаєте (якщо ваші великі, товсті пальці прикривають її). Це спливаюче меню з вибором Для цього слід ознайомитися з поданням кандидатів .

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@android:color/white"
    android:textColor="@android:color/black"
    android:textSize="30sp">
</TextView>

3. Додайте підтримуючі файли xml

Створіть xmlу своїй resпапці папку. (Клацніть правою кнопкою миші resта виберіть Створити> Каталог .)

Потім додайте до нього два наступні файли xml. (Клацніть правою кнопкою миші xmlпапку та виберіть Створити> Файл ресурсів XML .)

  • number_pad.xml
  • метод.xml

number_pad.xml

Саме тут воно починає ставати цікавішим. Це Keyboardвизначає компонування клавіш .

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="20%p"
    android:horizontalGap="5dp"
    android:verticalGap="5dp"
    android:keyHeight="60dp">

    <Row>
        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
        <Key android:codes="50" android:keyLabel="2"/>
        <Key android:codes="51" android:keyLabel="3"/>
        <Key android:codes="52" android:keyLabel="4"/>
        <Key android:codes="53" android:keyLabel="5" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="left"/>
        <Key android:codes="55" android:keyLabel="7"/>
        <Key android:codes="56" android:keyLabel="8"/>
        <Key android:codes="57" android:keyLabel="9"/>
        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="-5"
             android:keyLabel="DELETE"
             android:keyWidth="40%p"
             android:keyEdgeFlags="left"
             android:isRepeatable="true"/>
        <Key android:codes="10"
             android:keyLabel="ENTER"
             android:keyWidth="60%p"
             android:keyEdgeFlags="right"/>
    </Row>

</Keyboard>

Ось декілька речей, які слід зазначити:

  • keyWidth: Це ширина за замовчуванням кожної клавіші. Це 20%pозначає, що кожна клавіша повинна займати 20% від ширини р- ну. Це може бути замінено окремими клавішами, хоча, як ви бачите, це трапилося з клавішами Видалити та Ввести в третьому ряду.
  • keyHeight: Тут важко закодовано, але ви можете використовувати щось на зразок, @dimen/key_heightщоб динамічно встановити його для різних розмірів екрана.
  • Gap: Горизонтальний і вертикальний зазор вказує, скільки місця залишиться між клавішами. Навіть якщо ви встановите це 0px, все одно невеликий проміжок.
  • codes: Це може бути Unicode або спеціальне значення коду, яке визначає, що відбувається або що вводиться при натисканні клавіші. Перевірте, keyOutputTextчи хочете ви ввести довший рядок Unicode.
  • keyLabel: Це текст, який відображається на клавіші.
  • keyEdgeFlags: Це вказує, до якого краю слід вирівняти ключ.
  • isRepeatable: Якщо ви утримуєте клавішу, вона продовжуватиме повторювати введення.

метод.xml

Цей файл повідомляє системі доступні підтипи методу введення. Я просто включаю тут мінімальну версію.

<?xml version="1.0" encoding="utf-8"?>
<input-method
    xmlns:android="http://schemas.android.com/apk/res/android">

    <subtype
        android:imeSubtypeMode="keyboard"/>

</input-method>

4. Додайте код Java для обробки введення ключа

Створіть новий файл Java. Давайте назвемо це MyInputMethodService. Цей файл пов'язує все разом. Він обробляє вхід, отриманий з клавіатури, і надсилає його будь-якому виду, який він отримує ( EditTextнаприклад,).

public class MyInputMethodService extends InputMethodService implements KeyboardView.OnKeyboardActionListener {

    @Override
    public View onCreateInputView() {
        // get the KeyboardView and add our Keyboard layout to it
        KeyboardView keyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard_view, null);
        Keyboard keyboard = new Keyboard(this, R.xml.number_pad);
        keyboardView.setKeyboard(keyboard);
        keyboardView.setOnKeyboardActionListener(this);
        return keyboardView;
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {

        InputConnection ic = getCurrentInputConnection();
        if (ic == null) return;
        switch (primaryCode) {
            case Keyboard.KEYCODE_DELETE:
                CharSequence selectedText = ic.getSelectedText(0);
                if (TextUtils.isEmpty(selectedText)) {
                    // no selection, so delete previous character
                    ic.deleteSurroundingText(1, 0);
                } else {
                    // delete the selection
                    ic.commitText("", 1);
                }
                break;
            default:
                char code = (char) primaryCode;
                ic.commitText(String.valueOf(code), 1);
        }
    }

    @Override
    public void onPress(int primaryCode) { }

    @Override
    public void onRelease(int primaryCode) { }

    @Override
    public void onText(CharSequence text) { }

    @Override
    public void swipeLeft() { }

    @Override
    public void swipeRight() { }

    @Override
    public void swipeDown() { }

    @Override
    public void swipeUp() { }
}

Примітки:

  • У OnKeyboardActionListenerпрослуховує введення з клавіатури. Також потрібні всі ці порожні методи в цьому прикладі.
  • Це InputConnectionте, що використовується для надсилання вводу на інший вид, як-от an EditText.

5. Оновіть маніфест

Я ставлю це останнє, а не перше, оскільки воно стосується файлів, які ми вже додали вище. Щоб зареєструвати власну клавіатуру як системну клавіатуру, потрібно додати serviceрозділ у файл AndroidManifest.xml . Помістіть його в applicationрозділі після activity.

<manifest ...>
    <application ... >
        <activity ... >
            ...
        </activity>

        <service
            android:name=".MyInputMethodService"
            android:label="Keyboard Display Name"
            android:permission="android.permission.BIND_INPUT_METHOD">
            <intent-filter>
                <action android:name="android.view.InputMethod"/>
            </intent-filter>
            <meta-data
                android:name="android.view.im"
                android:resource="@xml/method"/>
        </service>

    </application>
</manifest>

Це воно! Ви можете мати змогу запустити додаток зараз. Однак ви не побачите багато, доки не включите клавіатуру в налаштуваннях.

6. Увімкніть клавіатуру в Налаштуваннях

Кожен користувач, який хоче використовувати вашу клавіатуру, повинен увімкнути її в налаштуваннях Android. Детальні вказівки, як це зробити, дивіться за наступним посиланням:

Ось підсумок:

  • Перейдіть у Налаштування Android> Мови та введення> Поточна клавіатура> Виберіть клавіатури.
  • Ви повинні побачити свою власну клавіатуру у списку. Увімкніть це.
  • Поверніться та знову виберіть Поточна клавіатура. Ви повинні побачити свою власну клавіатуру у списку. Виберіть його.

Тепер ви маєте можливість використовувати клавіатуру в будь-якому місці, де ви можете ввести Android.

Подальше навчання

Клавіатуру вище можна використовувати, але щоб створити клавіатуру, якою захочуть користуватися інші люди, вам, мабуть, доведеться додати більше функціональних можливостей. Вивчіть посилання нижче, щоб дізнатися як.

Продовжувати

Вам не подобається, як стандарт KeyboardViewвиглядає і поводиться? Я, звичайно, ні. Схоже, він не оновлювався з Android 2.0. Як щодо всіх тих користувацьких клавіатур у магазині Play? Вони не схожі на потворну клавіатуру вгорі.

Хороша новина полягає в тому, що ви можете повністю налаштувати зовнішній вигляд та поведінку своєї клавіатури. Вам потрібно буде зробити наступні дії:

  1. Створіть свій власний перегляд клавіатури для підкласів ViewGroup. Ви можете заповнити її Buttons або навіть скласти власні спеціальні перегляди ключів, які є підкласом View. Якщо ви використовуєте спливаючі вікна, то зауважте це .
  2. Додайте на клавіатурі користувальницький інтерфейс слухача подій . Назвіть його методи для таких речей, як onKeyClicked(String text)або onBackspace().
  3. Вам не потрібно додати keyboard_view.xml, key_preview.xmlабо number_pad.xmlописані в напрямках вище , так як це все для стандарту KeyboardView. Ви будете обробляти всі ці аспекти інтерфейсу користувача у своєму власному представленні.
  4. У своєму MyInputMethodServiceкласі реалізуйте користувальницький слухач клавіатури, визначений у класі клавіатури. Це замість того KeyboardView.OnKeyboardActionListener, що вже не потрібно.
  5. У методі вашого MyInputMethodServiceкласу onCreateInputView()створіть і поверніть екземпляр спеціальної клавіатури. Не забудьте встановити спеціальний слухач клавіатури на this.

35

Клавіатура в додатку

Ця відповідь розповідає про те, як зробити власну клавіатуру для використання виключно у вашому додатку. Якщо ви хочете зробити системну клавіатуру, яку можна використовувати в будь-якому додатку, перегляньте іншу мою відповідь .

Приклад буде виглядати приблизно так. Ви можете змінити його для будь-якої розкладки клавіатури.

введіть тут опис зображення

1. Почніть новий проект Android

Я назвав свій проект InAppKeyboard. Телефонуйте своїм, що завгодно.

2. Додайте файли компонування

Розкладка клавіатури

Додати файл макета до res/layoutпапки. Я зателефонував своєму keyboard. Клавіатура - це спеціальний складний вид, який ми надуваємо з цього файлу макета xml. Ви можете використовувати будь-який макет, який вам подобається, щоб упорядкувати ключі, але я використовую LinearLayout. Зверніть увагу на mergeтеги.

res / layout / keyboard.xml

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/button_1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="1"/>

            <Button
                android:id="@+id/button_2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="2"/>

            <Button
                android:id="@+id/button_3"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="3"/>

            <Button
                android:id="@+id/button_4"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="4"/>

            <Button
                android:id="@+id/button_5"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="5"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/button_6"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="6"/>

            <Button
                android:id="@+id/button_7"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="7"/>

            <Button
                android:id="@+id/button_8"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="8"/>

            <Button
                android:id="@+id/button_9"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="9"/>

            <Button
                android:id="@+id/button_0"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="0"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/button_delete"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:text="Delete"/>

            <Button
                android:id="@+id/button_enter"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:text="Enter"/>

        </LinearLayout>
    </LinearLayout>

</merge>

Макет діяльності

Для демонстраційних цілей наша діяльність є єдиною, EditTextа клавіатура внизу. Я назвав власний перегляд клавіатури MyKeyboard. (Ми незабаром додамо цей код, тому поки ігноруємо помилку.) Перевага введення всього нашого клавіатурного коду в єдиний вигляд полягає в тому, що це дозволяє легко повторно використовувати його в іншій діяльності або додатку.

res / layout / activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.inappkeyboard.MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#c9c9f1"
        android:layout_margin="50dp"
        android:padding="5dp"
        android:layout_alignParentTop="true"/>

    <com.example.inappkeyboard.MyKeyboard
        android:id="@+id/keyboard"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"/>

</RelativeLayout>

3. Додайте Java-файл клавіатури

Додайте новий файл Java. Я зателефонував своєму MyKeyboard.

Найголовніше , щоб відзначити тут, що не існує жорстка посилання на який - небудь EditTextабо Activity. Це дозволяє легко підключити його до будь-якого додатка чи діяльності, яка потребує цього. У цьому користувальницькому представленні клавіатури також використовується анкета InputConnection, яка імітує спосіб спілкування системної клавіатури з EditText. Так ми уникаємо жорстких посилань.

MyKeyboard являє собою складений вигляд, який надуває макет перегляду, який ми визначили вище.

MyKeyboard.java

public class MyKeyboard extends LinearLayout implements View.OnClickListener {

    // constructors
    public MyKeyboard(Context context) {
        this(context, null, 0);
    }

    public MyKeyboard(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyKeyboard(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    // keyboard keys (buttons)
    private Button mButton1;
    private Button mButton2;
    private Button mButton3;
    private Button mButton4;
    private Button mButton5;
    private Button mButton6;
    private Button mButton7;
    private Button mButton8;
    private Button mButton9;
    private Button mButton0;
    private Button mButtonDelete;
    private Button mButtonEnter;

    // This will map the button resource id to the String value that we want to 
    // input when that button is clicked.
    SparseArray<String> keyValues = new SparseArray<>();

    // Our communication link to the EditText
    InputConnection inputConnection;

    private void init(Context context, AttributeSet attrs) {

        // initialize buttons
        LayoutInflater.from(context).inflate(R.layout.keyboard, this, true);
        mButton1 = (Button) findViewById(R.id.button_1);
        mButton2 = (Button) findViewById(R.id.button_2);
        mButton3 = (Button) findViewById(R.id.button_3);
        mButton4 = (Button) findViewById(R.id.button_4);
        mButton5 = (Button) findViewById(R.id.button_5);
        mButton6 = (Button) findViewById(R.id.button_6);
        mButton7 = (Button) findViewById(R.id.button_7);
        mButton8 = (Button) findViewById(R.id.button_8);
        mButton9 = (Button) findViewById(R.id.button_9);
        mButton0 = (Button) findViewById(R.id.button_0);
        mButtonDelete = (Button) findViewById(R.id.button_delete);
        mButtonEnter = (Button) findViewById(R.id.button_enter);

        // set button click listeners
        mButton1.setOnClickListener(this);
        mButton2.setOnClickListener(this);
        mButton3.setOnClickListener(this);
        mButton4.setOnClickListener(this);
        mButton5.setOnClickListener(this);
        mButton6.setOnClickListener(this);
        mButton7.setOnClickListener(this);
        mButton8.setOnClickListener(this);
        mButton9.setOnClickListener(this);
        mButton0.setOnClickListener(this);
        mButtonDelete.setOnClickListener(this);
        mButtonEnter.setOnClickListener(this);

        // map buttons IDs to input strings
        keyValues.put(R.id.button_1, "1");
        keyValues.put(R.id.button_2, "2");
        keyValues.put(R.id.button_3, "3");
        keyValues.put(R.id.button_4, "4");
        keyValues.put(R.id.button_5, "5");
        keyValues.put(R.id.button_6, "6");
        keyValues.put(R.id.button_7, "7");
        keyValues.put(R.id.button_8, "8");
        keyValues.put(R.id.button_9, "9");
        keyValues.put(R.id.button_0, "0");
        keyValues.put(R.id.button_enter, "\n");
    }

    @Override
    public void onClick(View v) {

        // do nothing if the InputConnection has not been set yet
        if (inputConnection == null) return;

        // Delete text or input key value
        // All communication goes through the InputConnection
        if (v.getId() == R.id.button_delete) {
            CharSequence selectedText = inputConnection.getSelectedText(0);
            if (TextUtils.isEmpty(selectedText)) {
                // no selection, so delete previous character
                inputConnection.deleteSurroundingText(1, 0);
            } else {
                // delete the selection
                inputConnection.commitText("", 1);
            }
        } else {
            String value = keyValues.get(v.getId());
            inputConnection.commitText(value, 1);
        }
    }

    // The activity (or some parent or controller) must give us 
    // a reference to the current EditText's InputConnection
    public void setInputConnection(InputConnection ic) {
        this.inputConnection = ic;
    }
}

4. Наведіть клавіатуру на EditText

Для системних клавіатур Android використовує InputMethodManager для вказівки клавіатури на сфокусовану EditText. У цьому прикладі активність займе своє місце, надавши посилання від EditTextна нашу власну клавіатуру на.

Оскільки ми не використовуємо клавіатуру системи, нам потрібно відключити її, щоб не спливати при натисканні на EditText. По-друге, нам потрібно дістати InputConnectionз EditTextі передати його на нашу клавіатуру.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText editText = (EditText) findViewById(R.id.editText);
        MyKeyboard keyboard = (MyKeyboard) findViewById(R.id.keyboard);

        // prevent system keyboard from appearing when EditText is tapped
        editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
        editText.setTextIsSelectable(true);

        // pass the InputConnection from the EditText to the keyboard
        InputConnection ic = editText.onCreateInputConnection(new EditorInfo());
        keyboard.setInputConnection(ic);
    }
}

Якщо у вашій діяльності є кілька EditTexts, вам потрібно буде написати код, щоб передати потрібний EditText InputConnectionна клавіатуру. (Ви можете зробити це, додавши OnFocusChangeListenerта OnClickListenerредагувати редактори. Дивіться цю статтю для обговорення цього питання.) Ви також можете заховати або заховати клавіатуру у відповідний час.

Готово

Це воно. Ви повинні мати змогу запустити приклад програми зараз та ввести чи видалити текст за бажанням. Наступний ваш крок - змінити все, щоб відповідати вашим власним потребам. Наприклад, на деяких моїх клавіатурах я використовував TextViews, а не кнопки, тому що їх простіше налаштувати.

Примітки

  • У файлі макета xml ви також можете використовувати TextViewскоріше a, Buttonякщо ви хочете, щоб клавіші виглядали краще. Тоді просто зробіть фон малювальним, що змінює стан зовнішнього вигляду при натисканні.
  • Розширені спеціальні клавіатури: Для більшої гнучкості у зовнішньому вигляді клавіатури та перемиканні клавіатури я зараз створюю власні перегляди клавіш для цього підкласу Viewта спеціальні клавіатури для цього підкласу ViewGroup. Клавіатура розкладає всі клавіші програмно. Клавіші використовують інтерфейс для зв'язку з клавіатурою (подібно до того, як фрагменти спілкуються з діяльністю). Це не потрібно, якщо вам потрібна лише одна розкладка клавіатури, оскільки макет xml для цього добре працює. Але якщо ви хочете побачити приклад того, над чим я працював, перегляньте всі Key*та Keyboard*класи тут . Зауважте, що я також використовую там вигляд контейнера, функцією якого є заміна клавіатур в і вимкнення.

Ваша відповідь чудова, але як ми можемо встановити перемикання між оригінальною клавіатурою та цією новою клавіатурою.
Кішан Донга

@KishanDonga, На клавіатурі ви можете додати клавішу для переключення клавіатур. Коли користувач натискає на дзвінок InputMethodManager#showInputMethodPicker(). Якщо в оригінальній клавіатурі немає такої клавіші, єдиний спосіб, коли користувачі можуть переключитися на вашу клавіатуру, це зробити це вручну в системних налаштуваннях. Apple в цій області перевершує Android, оскільки Apple вимагає, щоб усі клавіатури мали клавішу перемикання клавіатури.
Сурагч

@KishanDonga, я щойно зрозумів, що ця відповідь стосується клавіатури в додатку, а не клавіатури системи. Якщо ви хочете поміняти місцями між двома спеціалізованими клавіатурами, ви можете програмно поміняти їх у вікні контейнера та вийти з нього. Просто додайте клавіш swap клавіатури на обох клавіатурах. Дивіться мою примітку та посилання "Удосконалені спеціальні клавіатури" у відповіді вище.
Сурагч

Якщо ви хочете проводити обмін між клавіатурою та клавіатурою системи, тоді схойте клавіатуру системи та покажіть її у відповідний час (і навпаки).
Сурагч

1
@MarekTakac, вам потрібно буде відключити системну клавіатуру та додати свою власну клавіатуру в кожній діяльності. Якщо у діяльності декілька EditTexts, вам потрібно буде додати onFocusChangedListenerдо них, щоб, коли вони отримали фокус, можна призначити InputConnectionпоточну EditTextдля вашої користувацької клавіатури.
Сурагч

31

Використання KeyboardView:

KeyboardView kbd = new KeyboardView(context);
kbd.setKeyboard(new Keyboard(this, R.xml.custom));

kbd.setOnKeyboardActionListener(new OnKeyboardActionListener() {
    ....
}

тепер у вас kbdє нормальний вигляд.

Приємним у цьому є те, що R.xml.customпосилається на те /res/xml/custom.xml, що визначає в xml макет клавіатури. Більш детальну інформацію про цей файл дивіться тут: Клавіатура , Клавіатура.Ров , Клавіатура.Ключ .


2
Я використовую клас KeyboardView, але щодо API 29 він тепер застарілий.
Абхіджіт

14

Ось зразок проекту для м’якої клавіатури.

https://developer.android.com/guide/topics/text/creating-input-method.html

Ваші повинні бути в одних рядках з іншим макетом.

Редагувати: Якщо вам потрібна клавіатура лише у вашій програмі, вона дуже проста! Створіть лінійний макет з вертикальною орієнтацією та створіть всередині нього 3 лінійних макета з горизонтальною орієнтацією. Потім розмістіть кнопки кожного рядка в кожному з цих горизонтальних лінійних макетів і призначте властивості ваги кнопкам. Використовуйте android: layout_weight = 1 для всіх, щоб вони були однаково розташовані.

Це вирішить. Якщо ви не отримали того, що очікували, будь ласка, опублікуйте код тут, і ми тут, щоб допомогти вам!


Редагування насправді погано, тому що це означає, що клавіатура завжди відображається і не буде вести себе як клавіатура Android.
m0skit0


4

Нещодавно я натрапив на цю публікацію, коли намагався вирішити, який метод використовувати для створення власної власної клавіатури. Я вважав, що API системи Android дуже обмежений, тому вирішив зробити власну клавіатуру в додатку. Використовуючи відповідь Сурагха як основу для мого дослідження, я продовжував розробляти свій власний компонент клавіатури . Він розміщений на GitHub з ліцензією MIT. Сподіваємось, це заощадить комусь ще багато часу і головний біль.

Архітектура досить гнучка. Є один основний вигляд (CustomKeyboardView), який можна вводити за допомогою будь-якої розкладки клавіатури та контролера.

Вам просто потрібно оголосити CustomKeyboardView у вашій діяльності xml (ви можете це робити і програмно):

    <com.donbrody.customkeyboard.components.keyboard.CustomKeyboardView
    android:id="@+id/customKeyboardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" />

Потім зареєструйте свої EditText з ним і скажіть, який тип клавіатури вони повинні використовувати:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val numberField: EditText = findViewById(R.id.testNumberField)
    val numberDecimalField: EditText = findViewById(R.id.testNumberDecimalField)
    val qwertyField: EditText = findViewById(R.id.testQwertyField)

    keyboard = findViewById(R.id.customKeyboardView)
    keyboard.registerEditText(CustomKeyboardView.KeyboardType.NUMBER, numberField)
    keyboard.registerEditText(CustomKeyboardView.KeyboardType.NUMBER_DECIMAL, numberDecimalField)
    keyboard.registerEditText(CustomKeyboardView.KeyboardType.QWERTY, qwertyField)
}

CustomKeyboardView обробляє решту!

У мене м'яч котиться за допомогою клавіатури Number, NumberDecimal і QWERTY. Сміливо завантажуйте його та створюйте власні макети та контролери. Це виглядає приблизно так:

gif краєвид Android клавіатури для Android

введіть тут опис зображення

Навіть якщо це не та архітектура, з якою ви вирішили піти, сподіваємось, вам буде корисно переглянути вихідний код робочої клавіатури в додатку.

Знову ось посилання на проект: Спеціальна клавіатура в додатку


2

Ну Сурагч дав найкращу відповідь поки що, але він пропустив деякі незначні речі, які були важливими для складання програми.

Я сподіваюся зробити кращу відповідь, ніж Сурагч, покращивши його відповідь. Я додам усі відсутні елементи, які він не виклав.

Я склав apk за допомогою програми Android, APK Builder 1.1.0. Тож почнемо.

Щоб створити додаток для Android, нам потрібно пару файлів і папок, які організовані у певному форматі та написані великими літерами відповідно.

res layout -> XML-файли, що зображають, як додаток буде виглядати на телефоні. Подібно до того, як html формує, як виглядає веб-сторінка у браузері. Дозволяє вашій програмі відповідно розміщуватися на екранах.

значень -> постійні дані, такі як кольори.xml, strings.xml, styles.xml. Ці файли повинні бути написані належним чином.

Dravable -> фотографії {jpeg, png, ...}; Назвіть їм що завгодно.

mipmap -> більше фотографій. використовується для піктограми додатка?

xml -> більше файлів xml.

src -> діє як JavaScript у html. Файли макета ініціюють перегляд старту, і ваш файл java буде динамічно керувати елементами тегів та запускати події. Події також можна активувати безпосередньо в layout.xml так само, як у html.

AndroidManifest.xml -> Цей файл реєструє, про що йдеться у вашій програмі. Назва програми, тип програми, необхідні дозволи тощо. Це, мабуть, робить Android досить безпечним. Програми буквально не можуть робити те, чого вони не просили у Маніфесті.

Зараз існує 4 типи програм для Android, діяльність, послуга, постачальник вмісту та приймач широкомовної програми. Наша клавіатура буде службою, яка дозволяє їй працювати у фоновому режимі. Він не з’явиться у списку програм, які потрібно запустити; але його можна видалити.

Щоб скласти додаток, передбачає Gradle та apk підписання. Ви можете дослідити цю програму або використовувати APK Builder для android. Це дуже просто.

Тепер, коли ми розуміємо розробку Android, давайте створимо файли та папки.

  1. Створіть файли та папки, як я вже говорив вище. Мій каталог буде виглядати наступним чином:

    • NumPad
      • AndroidManifest.xml
      • src
        • Сарагч
          • num_pad
            • MyInputMethodService.java
      • рез
        • креслярський
          • Suragch_NumPad_icon.png
        • макет
          • key_preview.xml
          • keyboard_view.xml
        • xml
          • метод.xml
          • number_pad.xml
        • значення
          • кольори.xml
          • strings.xml
          • styles.xml

Пам’ятайте, якщо ви використовуєте ідею, таку як Android Studio, вона може мати файл проекту.

  1. Запишіть файли.

A: NumPad / res / layout / key_preview.xml

<?xml version="1.0" encoding="utf-8"?>
   <TextView
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:gravity="center"
      android:background="@android:color/white"
      android:textColor="@android:color/black"
      android:textSize="30sp">
</TextView>

B: NumPad / res / layout / keyboard_view.xml

<?xml version="1.0" encoding="utf-8"?>
<android.inputmethodservice.KeyboardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:keyPreviewLayout="@layout/key_preview"
    android:layout_alignParentBottom="true">

</android.inputmethodservice.KeyboardView>

C: NumPad / res / xml / method.xml

<?xml version="1.0" encoding="utf-8"?>
<input-method  xmlns:android="http://schemas.android.com/apk/res/android">
    <subtype  android:imeSubtypeMode="keyboard"/>
</input-method>

D: Numpad / res / xml / number_pad.xml

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="20%p"
    android:horizontalGap="5dp"
    android:verticalGap="5dp"
    android:keyHeight="60dp">

    <Row>
        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
        <Key android:codes="50" android:keyLabel="2"/>
        <Key android:codes="51" android:keyLabel="3"/>
        <Key android:codes="52" android:keyLabel="4"/>
        <Key android:codes="53" android:keyLabel="5" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="left"/>
        <Key android:codes="55" android:keyLabel="7"/>
        <Key android:codes="56" android:keyLabel="8"/>
        <Key android:codes="57" android:keyLabel="9"/>
        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="-5"
             android:keyLabel="DELETE"
             android:keyWidth="40%p"
             android:keyEdgeFlags="left"
             android:isRepeatable="true"/>
        <Key android:codes="10"
             android:keyLabel="ENTER"
             android:keyWidth="60%p"
             android:keyEdgeFlags="right"/>
    </Row>

</Keyboard>

Звичайно, це можна легко редагувати на ваш смак. Ви навіть можете використовувати зображення замість lf слів для етикетки.

Suragch не продемонстрував файли в папці значень і припустив, що ми маємо доступ до Android Studio; що автоматично їх створює. Добре, що у мене є APK Builder.

E: NumPad / res / values ​​/ color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>

F: NumPad / res / values ​​/ strings.xml

<resources>
    <string name="app_name">Suragch NumPad</string>
</resources>

G: NumPad / res / values ​​/ styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>

H: Numpad / AndroidManifest.xml

Це файл, який справді був готовий до суперечки. Тут я відчував, що ніколи не буду складати свою програму. ридання. ридання. Якщо ви перевірите відповідь Сурака, ви побачите, що він залишає перший набір полів порожнім і додає тег активності у цей файл. Як я вже сказав, існують чотири типи програм для Android. Діяльність - це звичайний додаток із значком запуску. Ця цифра не є діяльністю! Далі він не здійснював жодної діяльності.

Мої друзі не включають тег активності. Ваша програма скомпілюватиметься, і при спробі запуску вона вийде з ладу! Що стосується xmlns: android та use-sdk; Я не можу вам там допомогти. Просто спробуйте мої налаштування, якщо вони працюють.

Як бачите, є тег служби, який реєструє його як послугу. Також service.android:name має бути назвою служби розширення публічного класу у нашому файлі Java. ЇЇ ОБОВ'ЯЗКОВО повинні бути використані з великої літери. Також пакет - це назва пакету, який ми оголосили у файлі java.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="Saragch.num_pad">

    <uses-sdk
        android:minSdkVersion="12"
        android:targetSdkVersion="27" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/Suragch_NumPad_icon"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <service
            android:name=".MyInputMethodService"
            android:label="Keyboard Display Name"
            android:permission="android.permission.BIND_INPUT_METHOD">

            <intent-filter>
                <action android:name="android.view.InputMethod"/>
            </intent-filter>

            <meta-data
                android:name="android.view.im"
                android:resource="@xml/method"/>

        </service>

    </application>
</manifest>

I: NumPad / src / Saragch / num_pad / MyInputMethodService.java

Примітка: Я думаю, що java є альтернативою src.

Це був ще один файл проблеми, але не такий спірний, як файл маніфесту. Як я знаю, Java досить добре, щоб знати, що таке, що ні. Я ледве знаю xml та як він пов'язаний з розробкою Android!

Проблема тут полягала в тому, що він нічого не імпортував! Я маю на увазі, він дав нам "повний" файл, який використовує імена, які неможливо було вирішити! InputMethodService, Keyboard тощо. Це погана практика, містер Сурагч. Дякую, що допомогли мені, але як ви очікували, що код буде зібраний, якщо імена не вдасться вирішити?

Далі йде правильно відредагована версія. Щойно я накинувся на пару натяків, щоб перевезти мене в потрібне місце, щоб дізнатися, що саме потрібно імпортувати.

package Saragch.num_pad;

import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.Keyboard;

import android.text.TextUtils;
import android.view.inputmethod.InputConnection;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;


public class MyInputMethodService extends InputMethodService implements KeyboardView.OnKeyboardActionListener 
{
    @Override
    public View onCreateInputView() 
    {
     // get the KeyboardView and add our Keyboard layout to it
     KeyboardView keyboardView = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard_view, null);
     Keyboard keyboard = new Keyboard(this, R.xml.number_pad);
     keyboardView.setKeyboard(keyboard);
     keyboardView.setOnKeyboardActionListener(this);
     return keyboardView;
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) 
    {

        InputConnection ic = getCurrentInputConnection();

        if (ic == null) return;

        switch (primaryCode)
        {
         case Keyboard.KEYCODE_DELETE:
            CharSequence selectedText = ic.getSelectedText(0);

            if (TextUtils.isEmpty(selectedText)) 
            {
             // no selection, so delete previous character
             ic.deleteSurroundingText(1, 0);
            }

            else 
            {
             // delete the selection
             ic.commitText("", 1);
            }

            ic.deleteSurroundingText(1, 0);
            break;

         default:
            char code = (char) primaryCode;
            ic.commitText(String.valueOf(code), 1);
        }
    }

    @Override
    public void onPress(int primaryCode) { }

    @Override
    public void onRelease(int primaryCode) { }

    @Override
    public void onText(CharSequence text) { }

    @Override
    public void swipeLeft() { }

    @Override
    public void swipeRight() { }

    @Override
    public void swipeDown() { }

    @Override
    public void swipeUp() { }
}
  1. Складіть і підпишіть свій проект.

    Ось де я незрозумілий як новий розробник Android. Я хотів би дізнатися це вручну, оскільки я вважаю, що справжні програмісти можуть збирати вручну.

Я думаю, градель - це один із інструментів для збирання та упаковки на apk. apk здається схожим на jar файл або rar для zip-файлу. Потім є два типи підписання. ключ налагодження, який заборонено використовувати в магазині гри та приватному ключі.

Добре, давайте руку містеру Сарагчу. І дякую за перегляд мого відео. Мовляв, підписуйтесь.


1

Була така ж проблема. Спочатку я використовував макет таблиці, але макет змінювався після натискання кнопки. Ця сторінка виявилася дуже корисною. http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-creating-a-numeric-keypad-with-gridlayout/


3
Не знаєте, де можна знайти спагетті. Приклад містить лише 5 рядків коду, що реалізує onCreate.
Гленн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.