Подтвердить что ты не робот

Создание SoftKeyboard с несколькими/альтернативными символами на ключ

Я следил за примерами developer.android.com относительно Методы ввода и воспроизведены с помощью приложения SoftKeyboard. Они вместе дают более чем достаточно информации о создании простой клавиатуры.

То, что я не вижу в API, - это возможность создавать альтернативные/множественные символы на ключ, который доступен на стандартной клавиатуре (LatinIME Keyboard).

enter image description here

Вышеупомянутое изображение является результатом длительного нажатия на клавишу "a". Когда вы долго нажимаете клавишу, вы можете заполнить всплывающее окно альтернативными символами.

enter image description here

Также можно дать подсказку всплывающих окон на некоторых клавишах, которые заставят пользователя нажать и удерживать клавишу, чтобы получить всплывающее меню.

До сих пор я не нашел ни одного источника информации о том, как это достигается, надеюсь, кто-то сможет дать мне начало, до тех пор я буду следовать исходному коду встроенной клавиатуры и посмотреть, будет ли я может перепроектировать его.

Изменить: Помогло бы, если developer.android.com ссылка на латинскую клавиатуру не ссылалась на изображение Sheep:) Фактический исходный код для LatinIME.java.

Изменить 2: В качестве ссылки, чем что-либо еще, это последовательность, в которой, как я полагаю, выполняется обычное действие longPress, чтобы показать всплывающее меню в KeyboardView.java:

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

Изменить 3:

Я до сих пор не понял этого: как добавить предложения ярлыков к клавишам? Ответ подсказывает, что он не встроен в API, и, действительно, я не нашел, чтобы этот код делал это. Однако на клавиатуре 2.3.4 (API 10) показана реализация этой функции:

enter image description here

Очень хотелось бы выяснить, как это делается ИТ, но это нигде в методе onDraw(), который я могу видеть, что заставляет меня думать, что он написан за пределами элемента KeyboardView. Однако я не могу найти файл layout, используемый для отображения элемента KeyboardView на встроенной клавиатуре. Если кто-нибудь знает, где его найти, возможно, это даст мне ключ, который мне нужен.

Изменить 4: Перемещенная клавиша Предварительный просмотр здесь, так как он слегка не соответствует теме:

Как отключить окно предварительного просмотра клавиатуры SoftKeyboard?

4b9b3361

Ответ 1

Реализация альтернативного всплывающего окна:

Для каждого ключа, который вы хотите использовать всплывающее меню, вы должны определить popupCharacters и popupKeyboard:

/res/xml/[Keyboard].xml

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

popupKeyboard - это XML-представление клавиатуры, используемой во всплывающем меню, содержащем альтернативные ключи:

/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>

Стилирование всплывающего окна альтернативного ключа:

Если вы хотите изменить макет/стиль всплывающего окна (по умолчанию это @android: layout/keyboard_popup_keyboard.xml), вы можете указать a android:popupLayout, который указывает на файл макета:

<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" />

Выполнение наложения предварительного просмотра ключей:

Единственное решение, которое я смог сбить вместе, чтобы показать предварительный просмотр ключа (без полной перезаписи исходного кода KeyboardView), находится ниже:

Обертка тега <KeyboardView> с помощью <FrameLayout> с высотой, указанной умножением keyHeight на количество строк. Внутри этого тега я просто создал LinearLayout для хранения строк, а затем LinearLayout для каждой строки, содержащей TextView с весом, равным значению% p, указанному для каждого <Key>:

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

И стиль:

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

Что производит это:

enter image description here

Я не буду счастлив, пока мне не удастся реализовать это так же, как это делает System Keyboard!

Ответ 2

Судя по моей собственной попытке кодирования программной клавиатуры, я узнал, что:

  • Для функций Nice/bling обычно требуется расширение KeyboardView и в основном писать большие части кода чертежа. К сожалению, вы не можете сделать это, переопределив некоторые ключевые методы, поскольку почти все является частным. Возможно, вам захочется взглянуть (и заимствовать код из:
    • (base)/core/java/android/inputmethodservice/KeyboardView.java (репортер кода ядра андроида)
    • (apps)/other/LatinIME/LatinKeyboardView.java (репортаж приложений ядра Android)

Обратите внимание, что овец на android.kernel.org должен сказать вам, что репо закрыто из-за взломщиков, но есть зеркала кода в другом месте (к сожалению, потеряли ссылки)

  • База KeyboardView не поддерживает тенированные подсказки, вы должны закодировать свой собственный KeyboardView, чтобы получить возможность переопределить onDraw ().

Теперь о том, что вы можете сделать:

  • Вы можете решить эту проблему, предоставив картинки для ключей: для этого используйте xml <Key ... android:keyIcon="@drawable/this_key_icon_file />. К сожалению, у вас наверняка будут плохие результаты для писем с этим методом (проблемы с разрешением).

  • Вы можете использовать (и настраивать внешний вид) всплывающей клавиатуры, которая появляется при длительном нажатии.

Объявите шаблон клавиатуры 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>

Объявить строковые значения, содержащие нужные клавиши на этой клавиатуре res/values/strings.xml:

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

Затем используйте оба варианта определения раскладки клавиатуры:

<Key android:codes="97" android:keyLabel="a"  
    android:popupKeyboard="@xml/kbd_popup_template"
    android:popupCharacters="@string/alternates_for_a" />
  • Вы также можете использовать функцию двойного касания, тройного касания,... для генерации альтернатив для ключа, который вы используете. Для этого просто используйте список для кодов клавиш Android:

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

произведет 97 = 'a' для одного крана, 224 = 'à' для двойного касания и 230 = 'æ' для тройного крана.

Продолжительность рассмотрения двойного нажатия - 800 мс в исходном коде Android. Он, к сожалению, жестко запрограммирован (и немного высокий, я чувствую).

Имейте в виду, что при двойном нажатии он сначала отправляет 'a', затем на втором касании посылает 'à'. Некоторым приложениям это не понравится.

Ответ 3

Эта всплывающая клавиатура с кнопкой закрытия раздражает, когда у нас есть только один всплывающий символ. Более простой способ - переопределить метод onLongPress класса KeyboardView следующим образом.

@Override
protected boolean onLongPress(Key key) {
    if (key.codes[0] == '1') {
        getOnKeyboardActionListener().onKey('!', null);
        return true;
    }
}

Ответ 4

Если вы хотите иметь текст поверх своего ключа, вы можете сделать это в методе onDraw() в своем классе, который переопределяет 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
            {}
        }
    }
}

Ответ 5

Для тех, кто пытается отклонить всплывающее меню, нажав вне его области просмотра, мне посчастливилось положить TouchListener в KeyboardView внутри класса, расширяющего 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 showing
                }
                return false;
            }
        });

        return mInputView;
    }
// The rest of your ime ...
}