使用每个键多个/备用字符创build一个SoftKeyboard
我已经遵循了关于input法的 developer.android.com上的示例,并使用SoftKeyboard示例应用程序进行播放。 这些共同提供了足够的关于创build简单键盘的信息。
我在API中看不到的是,可以在标准键盘(LatinIME键盘)上为每个键创build替代/多个字符。
上图是长按“a”键的结果。 当你长按一个键时,可以使用替代字符填充popup框。
也可以在某些按键上popup一个提示,提示用户按住一个按键来获得popup式菜单。
到目前为止,我还没有find关于如何实现的单一信息来源,希望有人能够给我一个开始,直到那时我会遵循内置键盘的源代码,看看我是否可以逆向工程它。
编辑:如果developer.android.com的链接到LatinIME键盘没有链接到一张羊的图片会有所帮助:) LatinIME.java的实际源代码。
编辑2:更多作为参考比其他任何事情,这是序列我相信一个通常的longPress行动通过为了显示在KeyboardView.javapopup式键盘:
onTouchEvent() onModifiedTouchEvent() mHandkler.handleMessage() with MSG_LONGPRESS openPopupIfRequired() onLongPress()
编辑3:
我仍然没有想到这一点 – 你如何添加标签build议的关键? 一个答案表明,它不是内置到API中,实际上我没有find代码来做到这一点。 但2.3.4(API 10)上的键盘显示了正在实现的function:
非常想知道IT是如何实现的,但是我不能看到onDraw()
方法中的任何地方 – 这使我相信它正在被编写在KeyboardView元素之外。 我不能findlayout
文件用于显示内置的键盘上的KeyboardView元素 – 如果有人知道在哪里可以find这可能会给我线索我需要的。
编辑4:移动键在这里预览的问题,因为它是有点偏离主题:
如何禁用SoftKeyboard键预览窗口?
实现备用按键popup:
对于每个你想要有一个popup式键盘的键,你应该定义popupCharacters和popupKeyboard :
/res/xml/[Keyboard].xml
<Key android:keyLabel="(" android:popupKeyboard="@xml/keyboard_popup_template" android:popupCharacters="[{<" />
popupKeyboard
是在包含替代键的popup窗口中使用的键盘的XML表示forms:
/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>
devise替代键popup式样:
如果要更改popup窗口的布局/样式(默认为@android:layout / keyboard_popup_keyboard.xml ),可以指定一个指向布局文件的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源代码)的唯一解决scheme如下:
用<FrameLayout>
包装<KeyboardView>
标签,其高度由keyHeight乘以行数指定。 在这个标签中,我简单地创build了一个LinearLayout来存放行,然后一个LinearLayout包含一个TextView,它的权重等于每个<Key>
指定的%p值:
<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>
这产生这个:
直到我像系统键盘那样设法实现这个function,我才开心!
从我自己编写软键盘的尝试来看,我发现:
- 尼斯/金光闪闪的function通常需要扩展
KeyboardView
并基本上写大部分的绘图代码。 不幸的是,你不能通过重写一些关键的方法来做到这一点, 你可能想看看(并借用一些代码:-
(base)/core/java/android/inputmethodservice/KeyboardView.java
(android核心代码回购) -
(apps)/other/LatinIME/LatinKeyboardView.java
(android核心应用程序回购)
-
请注意,android.kernel.org上的羊在那里告诉你,回购是由于cookiesclosures,但在别处的代码镜像(不幸的是失去了链接)
- 基础
KeyboardView
不支持阴影键提示,您必须编写您自己的KeyboardView才能有机会覆盖onDraw()方法。
现在你可以做什么:
-
你可以通过提供关键字的图片来解决这个问题:使用xml
<Key ... android:keyIcon="@drawable/this_key_icon_file />
这样做,不幸的是,问题)。 -
您可以使用(和configuration外观)长按出现的popup式键盘。
声明一个键盘模板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
声明包含你想要的键的string值:
<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" />
-
您还可以使用双击,三击,…function为您正在点击的按键生成交替。 为此,只需使用android keycodes的列表 :
<Key android:codes="97,224,230" .../>
对于单抽头将产生97 =“ a
”,对于双抽头将产生224 =“ à
”,对于三抽头将产生230 =“ æ
”。
Android源代码中考虑双击的时间长度设置为800ms。 不幸的是硬编码(有点高,我觉得)。
请注意,当双击时,它基本上首先发送一个' a
',然后在第二个水龙头发送' à
'。 有些应用程序,不会喜欢这个。
当我们只有一个popup式字符时,那个带有closuresbutton的popup式键盘很烦人。 更简单的方法是像这样覆盖KeyboardView类的onLongPress方法。
@Override protected boolean onLongPress(Key key) { if (key.codes[0] == '1') { getOnKeyboardActionListener().onKey('!', null); return true; } }
如果你想在你的键上有一个文本,你可以在你的类的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 {} } } }
对于任何试图通过点击外部视图区域来closurespopup式键盘的人来说,我已经有一些运气将TouchListener
放在类TouchListener
中的KeyboardView
内
public class YourIME extends InputMethodService{ @Override public View onCreateInputView() { mInputView = (LatinKeyboardView) getLayoutInflater().inflate(R.layout.input, null); setLatinKeyboard(mQwertyKeyboard); mInputView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if(motionEvent.getAction() == MotionEvent.ACTION_DOWN) { mInputView.closing(); // Close popup keyboard if it's showing } return false; } }); return mInputView; } // The rest of your ime ... }