默认情况下,如何使用符号模式显示Android键盘?
我有一个默认情况下,如何使用符号模式显示Android键盘?,android,android-softkeyboard,android-keypad,android-inputtype,Android,Android Softkeyboard,Android Keypad,Android Inputtype,我有一个EditText组件,当然,如果你点击它,就会显示Android键盘,允许用户输入文本。据我所知,所有Android软件键盘(至少)都有字母模式(ABC)和符号模式(?123)。它们的默认视图是字母模式 现在,当单击EditText组件时显示键盘时,我希望默认显示符号模式。用户仍可以切换到字母模式 有没有办法做到这一点?如果是,如何设置?我相信您希望设置编辑文本的输入类型 我不确定你会用哪一个,尽管你可能需要玩一会儿 我同意这是一种输入类型。如果希望仅向用户显示数字,则应将以下内容添
EditText
组件,当然,如果你点击它,就会显示Android键盘,允许用户输入文本。据我所知,所有Android软件键盘(至少)都有字母模式(ABC
)和符号模式(?123
)。它们的默认视图是字母模式
现在,当单击EditText
组件时显示键盘时,我希望默认显示符号模式。用户仍可以切换到字母模式
有没有办法做到这一点?如果是,如何设置?我相信您希望设置编辑文本的输入类型
我不确定你会用哪一个,尽管你可能需要玩一会儿 我同意这是一种输入类型。如果希望仅向用户显示数字,则应将以下内容添加到xml文档中以用于编辑文本:
android:inputType="number"
但是,如果将其设置为数字,则用户必须输入一个数字。但您可以添加其他类型,如号码和电子邮件地址,例如:
android:inputType="number|textEmailAddress"
查看更多选项。您还可以查看eclipse或android studio在“inputType”下显示的内容。唯一的方法是设置
编辑文本的inputType
如果要在onCreate()
中(或在自定义视图的构造函数中)设置此属性,可以使用以下方法:
否则,如果需要在onCreate()
之后(或在自定义视图的构造函数之后)设置此属性,则可以使用以下方法:
显然,您还可以在XML级别指定属性:
android:inputType="number|numberDecimal"
您可以使用不同的标志来查找最佳组合过滤器。我之所以发布这篇文章,是因为我认为没有任何答案真正解决了这个问题。问题中的屏幕截图与特定InputType的默认状态不对应。因此,切换输入类型不会从屏幕截图中显示布局
(根据我的研究…)
对符号输入的支持不受任何合同的约束。在创建自己的InputMethod
时,可以很好地省略符号。或者,他们可以添加分页支持,以提供对100个符号的访问。这能受合同约束吗?可能是。但是,现在不是
输入法框架不允许客户端和IME之间进行直接通信。所有通信都通过InputMethodManager
或通过InputConnection
单向通道进行。然而,使用?123
切换到符号是一个内部事件,而不是一个定义的状态/动作。客户端应用程序无法切换到它。没有公开(或隐藏)的API来实现这一点
InputType
表示与IME完全不同的内容。不知道为什么每个人都推荐使用它当然,您可能会发现特定的InputType
提供了大多数所需的键。但这与默认情况下用符号模式显示Android键盘不同。
可能的解决方法:
我们将创建一个自定义的EditText
。我们不必。它会把所有东西都放在一个地方,把我们从复制粘贴的噩梦中解救出来
public class CusEditText extends EditText {
private final int mDefinedActionId;
public CusEditText(Context context, AttributeSet attrs) {
super(context, attrs);
// Corresponds to 'android:imeActionId' value
mDefinedActionId = getResources().getInteger(R.integer.definedActionId);
setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
Log.i("CusEditText", "onEditorAction, actionId = " + actionId);
// Only bother if (...)
if (actionId == mDefinedActionId) {
// Check if current InputType is NUMBER
if ((getInputType() & InputType.TYPE_CLASS_NUMBER) != 0) {
// Toggle
setImeActionLabel("NUM", mDefinedActionId);
setInputType(InputType.TYPE_CLASS_TEXT);
} else {
// Current InputType is TEXT // Toggle
setImeActionLabel("ABC", mDefinedActionId);
setInputType(InputType.TYPE_CLASS_NUMBER);
}
// We've handled this
return true;
}
// Let someone else worry about this
return false;
}
});
}
}
接下来,我们需要定义definedActionId
。打开或创建res/values/integers.xml
并添加:
<integer name="definedActionId">-100</integer>
没什么好解释的。IME将以数字模式启动。它将显示ABC
,而不是复选标记图标。单击后,我们截取actionId并在数字和文本输入之间切换。我们使用的是setInputType(…)
,因为它不仅更新了InputType
,还通过更改重新启动IMEsetRawInputType(…)
仅更新InputType
问题:
正如你所知,这并不是一个真正的解决方案。如果用户在文本模式下关闭键盘(使用后退
按钮),则再次打开键盘时,键盘将保持在文本模式。要进入数字模式,用户必须单击NUM
。此外,在文本模式下,用户将看到NUM
以及?123
选项作为操作。这不会破坏任何东西,但会从用户体验中带走
由于上面列出的原因,我们无法对以文本模式显示的?123
执行任何操作。但是,我们可以尝试确保键盘始终以数字模式打开。我将提供一个我们将如何做到这一点的草图。这不是直截了当的,因为我们(开发人员)不知道键盘关闭或打开之类的事件。更新的CusEditText
:
public class CusEditText extends EditText {
private final int mDefinedActionId;
private long mLastEditorActionTime = 0L;
public CusEditText(Context context, AttributeSet attrs) {
super(context, attrs);
// Corresponds to 'android:imeActionId' value
mDefinedActionId = getResources().getInteger(R.integer.definedActionId);
setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
Log.i("CusEditText", "onEditorAction, actionId = " + actionId);
// Only bother if (...)
if (actionId == mDefinedActionId) {
// setInputType(...) will restart the IME
// and call finishComposingText()
// see below
mLastEditorActionTime = SystemClock.elapsedRealtime();
// Check if current InputType is NUMBER
if ((getInputType() & InputType.TYPE_CLASS_NUMBER) != 0) {
// Toggle
setImeActionLabel("NUM", mDefinedActionId);
setInputType(InputType.TYPE_CLASS_TEXT);
} else {
// Current InputType is TEXT // Toggle
setImeActionLabel("ABC", mDefinedActionId);
setInputType(InputType.TYPE_CLASS_NUMBER);
}
// We've handled this
return true;
}
// Let someone else worry about this
return false;
}
});
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
return new CusInputConnectionWrapper(inputConnection, false);
}
private class CusInputConnectionWrapper extends InputConnectionWrapper {
private CusInputConnectionWrapper(InputConnection target, boolean mutable) {
super(target, mutable);
}
@Override
public boolean finishComposingText() {
Log.i("CICW", "finishComposingText");
// Ignore finishComposingText for 1 second (1000L)
if (SystemClock.elapsedRealtime() - mLastEditorActionTime > 1000L) {
if ((getInputType() & InputType.TYPE_CLASS_NUMBER) == 0) {
// InputConnection is no longer valid.
// Switch back to NUMBER iff required
setImeActionLabel("ABC", mDefinedActionId);
setInputType(InputType.TYPE_CLASS_NUMBER);
}
}
return super.finishComposingText();
}
}
}
同样,代码是自解释的。我们创建一个InputConnectionWrapper
并侦听finishComposingText()
回调。如果我们在文本
和数字
之间手动切换,我们将使用一个标志,因为finishComposingText()
将自动调用。否则,我们将检查输入类型是否设置为TEXT
,并将其更改为NUMBER
。我不确定finishComposingText()
是否是解释键盘关闭/打开的正确方法。在API 21上测试,香草安卓,这似乎是可行的。还需要进行更多的测试
我真的希望有人能想出一个比这更好、更健壮的解决方案——或者修改我的工作环境,使它看起来不像这样
摘要
手头的任务是围绕现有的输入法引擎(IME)提供数字和文本输入模式之间切换的功能。第一种方法是在切换机制中使用。这种方法在谷歌的键盘()上运行良好,但在三星的(没有)上却失败了。可能的解决方法是在应用程序自己的UI中包含切换按钮
即使使用谷歌的键盘,字母(文本)也无法显示
<integer name="definedActionId">-100</integer>
<com.your.packagename.CusEditText
android:layout_width="blah"
android:layout_height="blah"
android:inputType="number"
android:imeActionId="@integer/definedActionId"
android:imeActionLabel="ABC"/>
<!-- Probably use @string resource in place of ABC -->
public class CusEditText extends EditText {
private final int mDefinedActionId;
private long mLastEditorActionTime = 0L;
public CusEditText(Context context, AttributeSet attrs) {
super(context, attrs);
// Corresponds to 'android:imeActionId' value
mDefinedActionId = getResources().getInteger(R.integer.definedActionId);
setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
Log.i("CusEditText", "onEditorAction, actionId = " + actionId);
// Only bother if (...)
if (actionId == mDefinedActionId) {
// setInputType(...) will restart the IME
// and call finishComposingText()
// see below
mLastEditorActionTime = SystemClock.elapsedRealtime();
// Check if current InputType is NUMBER
if ((getInputType() & InputType.TYPE_CLASS_NUMBER) != 0) {
// Toggle
setImeActionLabel("NUM", mDefinedActionId);
setInputType(InputType.TYPE_CLASS_TEXT);
} else {
// Current InputType is TEXT // Toggle
setImeActionLabel("ABC", mDefinedActionId);
setInputType(InputType.TYPE_CLASS_NUMBER);
}
// We've handled this
return true;
}
// Let someone else worry about this
return false;
}
});
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
return new CusInputConnectionWrapper(inputConnection, false);
}
private class CusInputConnectionWrapper extends InputConnectionWrapper {
private CusInputConnectionWrapper(InputConnection target, boolean mutable) {
super(target, mutable);
}
@Override
public boolean finishComposingText() {
Log.i("CICW", "finishComposingText");
// Ignore finishComposingText for 1 second (1000L)
if (SystemClock.elapsedRealtime() - mLastEditorActionTime > 1000L) {
if ((getInputType() & InputType.TYPE_CLASS_NUMBER) == 0) {
// InputConnection is no longer valid.
// Switch back to NUMBER iff required
setImeActionLabel("ABC", mDefinedActionId);
setInputType(InputType.TYPE_CLASS_NUMBER);
}
}
return super.finishComposingText();
}
}
}
editText.setOnKeyListener(new View.OnKeyListener()
{
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
Log.d("KeyBoard", "Keyboard Test Key Hit");
switch (keyCode) {
KeyEvent.KEYCODE_POUND:
if(editText.setInputType(InputType.TYPE_CLASS_TEXT);
{
editText.setInputType(InputType.TYPE_CLASS_TEXT);
return true;
}