Как вы можете сделать пользовательскую клавиатуру в Android? - PullRequest
81 голосов
/ 06 марта 2012

Я хочу сделать собственную клавиатуру.Я не знаю, как это сделать, используя XML и Java.Следующая картинка - модель клавиатуры, которую я хочу сделать.Для этого нужны только цифры.

enter image description here

Ответы [ 9 ]

73 голосов
/ 27 июля 2014

Прежде всего вам понадобится файл 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 / drawable-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() {
    }
};

Надеюсь, это поможет !!!

Большая часть кода найдена здесь

50 голосов
/ 06 июля 2017

Системная клавиатура

В этом ответе рассказывается, как создать пользовательскую системную клавиатуру, которую можно использовать в любом приложении, которое пользователь установил на своем телефоне. Если вы хотите создать клавиатуру, которая будет использоваться только в вашем приложении, см. Мой другой ответ .

Пример ниже будет выглядеть следующим образом. Вы можете изменить его для любой раскладки клавиатуры.

enter image description here

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

1. Начать новый проект Android

Я назвал свой проект "Custom Keyboard". Называй как хочешь. Здесь нет ничего особенного. Я просто оставлю MainActivity и "Привет, мир!" макет как есть.

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
  • method.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% от ширины p . Однако его можно переопределить отдельными ключами, как вы можете видеть, что произошло с клавишами Delete и Enter в третьем ряду.
  • keyHeight: здесь это жестко задано, но вы можете использовать что-то вроде @dimen/key_height для его динамической настройки для разных размеров экрана.
  • Gap: расстояние по горизонтали и вертикали показывает, сколько места осталось между клавишами. Даже если вы установите 0px, все еще будет небольшой разрыв.
  • codes: Это может быть Unicode или пользовательское кодовое значение, которое определяет, что происходит или что вводится при нажатии клавиши. См. keyOutputText, если вы хотите ввести более длинную строку Юникода.
  • keyLabel: этот текст отображается на клавише.
  • keyEdgeFlags: указывает, по какой кромке должен быть выровнен ключ.
  • isRepeatable: Если удерживать клавишу нажатой, она будет повторять ввод.

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>

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 - это то, что используется для отправки ввода в другое представление, например 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 Store?Они не похожи на уродливую клавиатуру выше.

Хорошей новостью является то, что вы можете полностью настроить внешний вид и поведение своей клавиатуры.Вам нужно будет сделать следующие вещи:

  1. Создать свой собственный вид клавиатуры, который подклассы ViewGroup.Вы можете заполнить его Button с или даже создать свои собственные пользовательские представления ключей, которые подкласс View.Если вы используете всплывающие окна, обратите внимание на .
  2. Добавьте пользовательский интерфейс прослушивателя событий на клавиатуре.Вызовите его методы для таких вещей, как onKeyClicked(String text) или onBackspace().
  3. Вам не нужно добавлять keyboard_view.xml, key_preview.xml или number_pad.xml, описанные в приведенных выше инструкциях, поскольку все они предназначены длястандарт KeyboardView.Вы будете обрабатывать все эти аспекты пользовательского интерфейса в своем пользовательском представлении.
  4. В своем классе MyInputMethodService реализуйте пользовательский слушатель клавиатуры, который вы определили в своем классе клавиатуры.Это вместо KeyboardView.OnKeyboardActionListener, который больше не нужен.
  5. В методе onCreateInputView() вашего класса MyInputMethodService создайте и верните экземпляр своей пользовательской клавиатуры.Не забудьте установить пользовательский слушатель клавиатуры на this.
30 голосов
/ 12 августа 2012

Использование 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 раскладку клавиатуры.Для получения дополнительной информации об этом файле, смотрите здесь: Клавиатура , Keyboard.Row , Keyboard.Key .

24 голосов
/ 10 июля 2017

Клавиатура в приложении

В этом ответе рассказывается, как создать собственную клавиатуру для использования исключительно в вашем приложении. Если вы хотите создать системную клавиатуру, которую можно использовать в любом приложении, тогда см. Мой другой ответ .

Пример будет выглядеть следующим образом. Вы можете изменить его для любой раскладки клавиатуры.

enter image description here

1. Начать новый проект Android

Я назвал свой проект InAppKeyboard. Называй свой как хочешь.

2. Добавьте файлы макета

Раскладка клавиатуры

Добавить файл макета в папку res/layout. Я назвал мой keyboard. Клавиатура будет составным составным представлением , которое мы надуваем из этого файла макета XML. Вы можете использовать любой макет, который вам нравится, чтобы расположить клавиши, но я использую LinearLayout. Обратите внимание на теги merge.

Рез / макет / 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. (Мы добавим этот код в ближайшее время, поэтому пока игнорируем ошибку.) Преимущество размещения всего нашего кода на клавиатуре в одном представлении заключается в том, что его легко использовать в другом действии или приложении.

Рез / макет / 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 к EditTexts. См. эту статью для обсуждения этого.) Вы также можете скрыть или показать свою клавиатуру в подходящее время.

Закончено

Вот и все. Теперь вы сможете запустить пример приложения и вводить или удалять текст по своему усмотрению. Ваш следующий шаг - изменить все под свои нужды. Например, в некоторых моих клавиатурах я использовал TextViews, а не Buttons, потому что их проще настраивать.

Примечания

  • В файле макета xml вы также можете использовать TextView вместо Button, если хотите, чтобы клавиши выглядели лучше. Затем просто сделайте фон рисованным, который при нажатии изменяет состояние внешнего вида.
  • Усовершенствованные пользовательские клавиатуры: для большей гибкости в отображении клавиатуры и ее переключении я сейчас делаю пользовательские виды клавиш, которые подкласс View, и пользовательские клавиатуры, которые подкласс ViewGroup.Клавиатура раскладывает все клавиши программно.Клавиши используют интерфейс для связи с клавиатурой (аналогично тому, как фрагменты взаимодействуют с действием).В этом нет необходимости, если вам нужна только одна раскладка клавиатуры, поскольку раскладка xml для этого отлично работает.Но если вы хотите увидеть пример того, над чем я работал, проверьте все Key* и Keyboard* классы здесь .Обратите внимание, что я также использую контейнерное представление, функция которого состоит в том, чтобы переключать и выгружать клавиатуры.
14 голосов
/ 06 марта 2012

Вот пример проекта для программной клавиатуры.

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

Вы должны быть в тех же строках с другим макетом.

Редактировать: Если вынужна клавиатура только в вашем приложении, это очень просто!Создайте линейный макет с вертикальной ориентацией и создайте в нем 3 линейных макета с горизонтальной ориентацией.Затем поместите кнопки каждой строки в каждую из этих горизонтальных линейных компоновок и присвойте кнопкам свойство веса.Используйте android: layout_weight = 1 для всех из них, чтобы они имели одинаковое расстояние.

Это решит проблему.Если вы не получили ожидаемого, отправьте код здесь, и мы здесь, чтобы помочь вам!

7 голосов
/ 09 февраля 2014

Один из лучших хорошо документированных примеров, которые я нашел.

http://www.fampennings.nl/maarten/android/09keyboard/index.htm

KeyboardView предоставляется связанный XML-файл и исходный код.

1 голос
/ 23 июля 2018

Я недавно сталкивался с этим постом, когда пытался решить, какой метод использовать для создания своей собственной клавиатуры. Я обнаружил, что 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. Не стесняйтесь загружать его и создавать свои собственные макеты и контроллеры. Это выглядит так:

android custom keyboard gif landscape

enter image description here

Даже если это не та архитектура, с которой вы решили пойти, надеюсь, будет полезно увидеть исходный код рабочей клавиатуры в приложении.

Опять же, вот ссылка на проект: Настраиваемая клавиатура в приложении

1 голос
/ 26 августа 2013

Была такая же проблема. Сначала я использовал макет таблицы, но после нажатия кнопки он менялся. Нашел эту страницу очень полезной, хотя. http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-creating-a-numeric-keypad-with-gridlayout/

0 голосов
/ 24 мая 2019

Ну, Сурагч дал лучший ответ, но пропустил некоторые мелочи, которые были важны для компиляции приложения.

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

Я скомпилировал свой apk с помощью приложения для Android APK Builder 1.1.0. Итак, начнем.

Чтобы создать приложение для Android, нам понадобится пара файлов и папок, которые организованы в определенном формате и соответственно написаны с большой буквы.

Рез макет -> XML-файлы с изображением приложения Телефон. Подобно тому, как HTML формирует как веб-страница выглядит в браузере. позволяющий ваше приложение, чтобы соответствовать на экранах соответственно.

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

drawable -> pics {jpeg, png, ...}; Назови их что-нибудь.

mipmap -> больше фото. используется для значка приложения?

xml -> другие файлы xml.

ЦСИ -> действует как JavaScript в HTML. расположение файлы будут запускать начальный вид и ваш файл Java будет динамически управлять элементами тега и триггером События. События также могут быть активированы прямо в layout.xml так же, как в HTML.

AndroidManifest.xml -> Этот файл регистрирует, о чем ваше приложение. Имя приложения, тип программы, необходимые разрешения и т. Д. Это делает Android довольно безопасным. Программы буквально не могут делать то, о чем они не просили в Манифесте.

В настоящее время существует 4 типа программ для Android: действие, услуга, поставщик контента и приемник вещания. Наша клавиатура станет сервисом, который позволит ей работать в фоновом режиме. Он не будет отображаться в списке приложений для запуска; но его можно удалить.

Для компиляции вашего приложения требуется gradle и apk-подпись. Вы можете исследовать это или использовать APK Builder для Android. Это супер просто.

Теперь, когда мы понимаем разработку Android, давайте создадим файлы и папки.

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

    • NumPad
      • AndroidManifest.xml
      • ЦСИ
        • Saragch
          • NUM_PAD
            • MyInputMethodService.java
      • Рез
        • вытяжка
          • Suragch_NumPad_icon.png
        • расположение
          • key_preview.xml
          • keyboard_view.xml
        • XML
          • method.xml
          • number_pad.xml
        • значения
          • colors.xml
          • strings.xml
          • styles.xml

Помните, что если вы используете ide, например 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>

Конечно, это можно легко отредактировать по своему вкусу. Вы даже можете использовать изображения вместо слов для метки.

Сурагч не продемонстрировал файлы в папке значений и предположил, что у нас есть доступ к Android Studio; который автоматически создает их. Хорошо, что у меня APK Builder.

E: NumPad / res / values ​​/ colors.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. Действие - это обычное приложение со значком запуска. Этот numpad не является деятельностью! Далее он не осуществлял никакой деятельности.

Мои друзья не включают тег активности. Ваша программа будет скомпилирована, и при попытке ее запуска произойдет сбой! Что касается xmlns: android и использует-sdk; Я не могу помочь вам там. Просто попробуйте мои настройки, если они работают.

Как видите, есть служебный тег, который регистрирует его как сервис. Также service.android:name должно быть именем расширенного сервиса публичного класса в нашем java-файле. Он ДОЛЖЕН быть прописан соответственно. Также package - это имя пакета, который мы объявили в 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. Я хотел бы выучить это вручную, так как считаю, что настоящие программисты могут компилировать вручную.

Я думаю, что gradle - это один из инструментов для компиляции и упаковки в apk. apk похоже на jar-файл или rar для zip-файла. Существует два типа подписи. ключ отладки, который не разрешен в магазине игр и закрытый ключ.

Хорошо, давайте поможем мистеру Сарагчу. И спасибо за просмотр моего видео. Нравится, подписывайтесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...