Создание 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?
Ответы
Ответ 1
Реализация альтернативного всплывающего окна:
Для каждого ключа, который вы хотите использовать всплывающее меню, вы должны определить popupCharacters и popupKeyboard:
/res/xml/[Keyboard].xml
<Key android:keyLabel="("
android:popupKeyboard="@xml/keyboard_popup_template"
android:popupCharacters="[{<" />
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 ...
}