我对Android原生开发很新,我正在试图弄清楚如何自定义IME动作按钮。我查看了Google文档,但我发现很少有关于预期行为的信息。
从offical guide我明白可以使用以下属性配置键盘操作按钮:
但经过一些经验尝试后,我发现API级别15与下一个API级别之间存在不同的行为。
我已经设置了一个具有以下属性的简单EditText元素:
<EditText
...
android:imeOptions="actionGo"
android:imeActionLabel="Custom"
android:imeActionId="666"
android:inputType="text"/>
我已经在纵向和横向模式下检查了不同API级别的效果。结果如下。
API级别15 - 4.0.3
在纵向模式下,键标签为 Go ,传递给回调方法的操作ID为2,相应于imeOptions设置。
在横向模式下,按键标签/ id为 Go / 2作为纵向模式,而输入区域中显示的按钮为 Custom / 666,相应于imeActionLabel和imeActionId属性。
API级别16,17和18 - 4.1.2,4.2.2和4.3
在纵向和横向模式下,键和按钮都显示为自定义标签,并且绑定到666 id,忽略imeOptions属性。
这种行为的不匹配非常烦人,因为:
你知道如何在API 15和16+中获得这个吗? 或者,如果有办法在API版本的所有(或至少部分)中获得一致的行为?
也许我在IME设置中遗漏了一些可以证明不同行为的东西......
非常感谢!
答案 0 :(得分:10)
只需在java代码中以编程方式调用.setImeActionLabel()
即可将actionID(再次)移至您想要的地址。
editText.setImeActionLabel(getString(R.string.xxx), EditorInfo.IME_ACTION_GO);
答案 1 :(得分:8)
实际上,输入法应用程序,而不是Android框架本身,决定如何处理您设置的值。
Android框架只是将您设置的值传递给输入法,然后输入法可以选择键盘上显示的按钮或者提取的&#34;全屏视图中的EditText
。 Android框架以两种方式影响EditorInfo
: -
通过EditorInfo.makeCompatible
传递,以确保其中的值在键盘和应用的targetApiVersion
之间兼容。目前,这仅影响某些InputType
值,而不是编辑器操作,但如果引入新的编辑器操作(或全新设置),这可能会发生变化。
它为输入法设置默认行为,包括全屏编辑器的行为。如果输入法选择不覆盖此默认行为,则最终可能会出现Android版本之间不同的行为。许多键盘确实选择以Android版本之间的一致方式设置自己的行为。
出于这个原因,说某个EditorInfo
字段对任何给定版本都有一定的影响并不是那么简单,并且无法确保一致的行为,甚至在一个Android版本上。您所做的只是为输入法提供提示,选择如何将其呈现给用户。
答案 2 :(得分:2)
如果有人正在为Android设计自定义键盘并且Enter键的标签出现问题,则应执行以下操作。在Android自定义键盘示例中,我们在SoftKeyboard.java中有以下方法:
@Override
public void onStartInput(EditorInfo attribute, boolean restarting)
{
super.onStartInput(attribute, restarting);
.
. // the implementation
.
mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
}
将最后一行更改为以下行:
mCurKeyboard.setImeOptions(getResources(), attribute);
现在在LatinKeyboard.java中更改setImeOptions方法,如bellow:
void setImeOptions(Resources res, EditorInfo ei)
{
if (mEnterKey == null)
{
return;
}
switch (ei.imeOptions & (EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION))
{
case EditorInfo.IME_ACTION_SEND:
mEnterKey.iconPreview = null;
mEnterKey.icon = null;
mEnterKey.label = res.getText(R.string.label_send_key);
break;
case EditorInfo.IME_ACTION_GO:
mEnterKey.iconPreview = null;
mEnterKey.icon = null;
mEnterKey.label = res.getText(R.string.label_go_key);
break;
case EditorInfo.IME_ACTION_NEXT:
mEnterKey.iconPreview = null;
mEnterKey.icon = null;
mEnterKey.label = res.getText(R.string.label_next_key);
break;
case EditorInfo.IME_ACTION_SEARCH:
mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_search);
mEnterKey.label = null;
break;
default:
mEnterKey.iconPreview = null;
mEnterKey.label = res.getText(R.string.label_enter_key);
mEnterKey.icon = null;
break;
}
if (ei.actionLabel != null)
{
mEnterKey.iconPreview = null;
mEnterKey.icon = null;
mEnterKey.label = ei.actionLabel;
}
}
现在,您的自定义键盘会根据imeActionLabel的xml文件中定义的内容显示正确的标签。
答案 3 :(得分:2)
当您启动一个新的Android项目时,它会为您的问题提供一个很好的提示。有一个名为LoginActivity
的活动,您可以将其创建为默认登录屏幕。此活动将生成EditText
,因为:
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:imeActionId="@+id/login"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"/>
现在,如果您阅读documentation,您就会知道imeOptions
属性允许您为文本字段指定其他操作。例如,弹出的键盘在右下角有一个动作,如“下一步”。使用imeOptions
,您可以从Android提供的预定义列表中选择其他操作。您可以指定类似“actionSend”或“actionSearch”的内容。
一旦这样做,按照Activity的顺序,您可以使用setOnEditorActionListener
事件处理程序监听该操作:
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == R.id.login || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
请注意我们如何定位imeActionId
。这是另一种在Activity中定位EditText
的方法,同时还可以灵活地更改键盘输入上的操作。