我有一个EditText
组件,当然,如果您单击它,就会显示 Android 键盘,允许用户输入文本。据我所知,所有 Android 软件键盘(至少)都有字母模式(ABC
)和符号模式(?123
)。他们的默认视图是字母模式。
现在,当EditText
单击组件时显示键盘时,我希望默认显示符号模式。用户仍然可以切换到字母模式。
有没有办法做到这一点?如果是,如何?
我有一个EditText
组件,当然,如果您单击它,就会显示 Android 键盘,允许用户输入文本。据我所知,所有 Android 软件键盘(至少)都有字母模式(ABC
)和符号模式(?123
)。他们的默认视图是字母模式。
现在,当EditText
单击组件时显示键盘时,我希望默认显示符号模式。用户仍然可以切换到字母模式。
有没有办法做到这一点?如果是,如何?
我发布这个是因为我认为任何答案都没有真正解决这个问题。问题中的屏幕截图与特定 InputType 的默认状态不对应。因此,切换 InputTypes 不会为您提供屏幕截图中的布局。
(根据我的研究...)
对符号输入的支持不受任何合同的约束。在创建自己的InputMethod
. 或者,他们可以添加分页支持以提供对 100 个符号的访问。这可以受合同约束吗?或许。但是,目前还不是。
输入法框架不允许客户端和 IME 之间直接通信。所有通信都通过InputMethodManager
或通过InputConnection
单向通道进行。?123
然而,切换到符号 using是一个内部事件,而不是定义的 state/action。客户端应用程序无法切换到它。没有公共(或隐藏)API 可以实现这一点。
InputType
表示与 IME 完全不同的东西。不知道为什么每个人都推荐使用它。您当然可能会发现一个特定的InputType
提供了大部分所需的密钥。但这不一样show[ing] Android keyboard with symbols mode by default.
可能的解决方法:
我们将创建一个自定义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>
-100
是一个任意值。我检查EditorInfo
了一下,actionIds ( IME_ACTION_XXXX
) >= 0。-100
似乎是个不错的候选者。
在 xml 中,您的布局将如下所示:
<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 -->
没什么好解释的。IME 将以 NUMBER 模式启动。它将显示 ,而不是复选标记图标ABC
。单击时,我们拦截 actionId 并在 NUMBER 和 TEXT 输入之间切换。我们之所以使用它,是setInputType(...)
因为它不仅会更新 . InputType
,而且还会通过更改重新启动 IME。setRawInputType(...)
只更新InputType
.
问题:
如您所知,这并不是真正的解决方案。如果用户在 TEXT 模式下关闭键盘(使用back
按钮),当他们再次打开键盘时,键盘将保持在 TEXT 模式。要进入 NUMBER 模式,用户必须单击NUM
。此外,在 TEXT 模式下,用户将看到NUM
操作以及?123
选项。这不会破坏任何东西,但确实会影响用户体验。
?123
由于上述原因,我们无法以 TEXT 模式显示。但是,我们可以尝试确保键盘始终以数字模式打开。我将提供一个粗略的草图,说明我们将如何做到这一点。它不是直截了当的,因为我们(开发人员)不知道诸如键盘关闭或打开之类的事件。更新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()
回调。如果我们在 and 之间手动切换TEXT
,NUMBER
我们会使用一个标志,因为finishComposingText()
会自动调用。否则,我们检查输入类型是否设置为TEXT
并将其更改为NUMBER
. 我不确定是否finishComposingText()
是解释键盘关闭/打开的正确方法。在 API 21、vanilla android 上进行测试,这似乎可行。将需要更多测试。
我真的希望有人能提出比这更好、更强大的解决方案——或者修改我的解决方法,使它看起来不像一个。
概括
手头的任务是提供围绕现有输入法引擎 (IME) 在数字和文本输入模式之间切换的功能。第一种方法是imeActionLabel & imeActionId
在切换机制中使用。这种方法适用于谷歌的键盘(这是 imeActionLabel),但三星的键盘失败了 -imeActionLabel
未能以纵向显示(没有extract)。可能的解决方法是在应用程序自己的 UI 中包含切换按钮。
即使使用 Google 的键盘,输入字母后模式切换回 NUMBER 时,字母(文本)也无法显示。flagNoExtractUi
此问题已通过使用阻止 IME 在横向进入全屏模式的标志修复(至少在测试设备上) 。
最终解决方案(待实施和测试)
EditText
)用于在 NUMBER 和 TEXT 模式之间切换有关尝试的方法的更多信息,请参阅此讨论线程。
截图
默认(数字):
切换到 TEXT:
我同意它是一个 InputType。如果您只想向您的用户显示数字,那么您可以将以下内容添加到您的 xml 文档中以用于您的编辑文本:
android:inputType="number"
但是,如果您将其设置为数字,则用户必须输入一个数字。但是您可以添加其他类型以及数字和电子邮件地址,例如:
android:inputType="number|textEmailAddress"
查看http://developer.android.com/reference/android/text/InputType.html了解更多选项。您还可以查看 eclipse 或 android studio 在“inputType”下显示的内容
我相信您正在寻找设置编辑文本的 InputType。
http://developer.android.com/reference/android/text/InputType.html
我不确定您会使用哪个,尽管您可能需要玩一会儿。
唯一的方法是设置你的EditText
.
如果要在onCreate()
(或在自定义View
的构造函数中)设置此属性,可以使用方法setRawInputType():
mEditText.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
否则,如果您需要在(或自定义的构造函数之后)设置此属性,则可以使用方法setInputType ():onCreate()
View
mEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
显然,您还可以在XML级别指定属性:
android:inputType="number|numberDecimal"
您可以使用不同的标志来找到最佳组合过滤器。
以编程方式,可以对通常的流程进行一些调整。首先,您必须将 editText 设置为:
editText.setInputType(InputType.TYPE_CLASS_NUMBER);
然后你必须听keyevent。按下磅时,再次将 InputType 设置为 InputType.TYPE_CLASS_TEXT。这应该对我有用。
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;
}
我已经回答过同样的事情我:默认情况下带有数字键盘的 EditText,但允许字母字符