我有一个EditText
组件,当然,如果点击它,会显示Android键盘,允许用户输入文字。据我所知,所有Android软件键盘都有(至少)字母模式(ABC
)和符号模式(?123
)。他们的默认视图是字母模式。
现在,当单击EditText
组件时显示键盘时,我希望默认显示符号模式。用户仍然可以切换到字母模式。
有没有办法实现这一目标?如果是,怎么样?
答案 0 :(得分:14)
我发布这个是因为我不认为任何答案实际上解决了这个问题。问题中的屏幕截图与特定InputType的默认状态不对应。因此,切换InputTypes不会从屏幕截图中为您提供布局。
(根据我的研究......)
对符号输入的支持不受任何合同的约束。在创建自己的InputMethod
时,可以很好地留下符号。或者,他们可以添加分页支持,以提供对100个符号的访问。这可以受合同约束吗?也许。但是,目前还没有。
输入法框架不允许客户端和IME之间的直接通信。所有通信都通过InputMethodManager
或InputConnection
- 单向频道进行。但是,使用?123
切换到符号是内部事件 - 不是已定义的状态/操作。客户端应用程序无法切换到它。没有公开(或隐藏)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
)是&gt; = 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
选项。这不会打破任何东西,但会从UX中消失。
由于上面列出的原因,我们无法对在TEXT模式下显示的?123
做任何事情。但是,我们可以尝试确保键盘始终在NUMBER模式下打开。我将提供一个粗略的草图,说明我们将如何做到这一点。它不直接,因为我们(开发人员)不知道键盘关闭或打开等事件。更新了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()
回调。如果我们在TEXT
和NUMBER
之间手动切换,我们会使用一个标记,因为会自动调用finishComposingText()
。否则,我们检查输入类型是否设置为TEXT
并将其更改为NUMBER
。我不确定finishComposingText()
是否是解释键盘关闭/打开的正确方法。测试API 21,香草android,这似乎工作。将需要更多测试。
我真的希望有人能提出比这更好,更强大的解决方案 - 或修改我的解决方法,使其看起来不像。
<强>摘要强>
目前的任务是提供在NUMBER&amp;之间切换的功能。围绕现有输入法引擎(IME)的TEXT输入模式。第一种方法是在切换机制中使用imeActionLabel & imeActionId
。这种方法适用于谷歌的键盘(this is the imeActionLabel),但三星的失败 - imeActionLabel
failed to show up in portrait(没有extract)。可能的解决方法是在应用程序自己的UI中包含切换按钮。
即使使用Google的键盘,输入字母后模式切换回NUMBER时字母(文本)也无法显示。通过使用标记flagNoExtractUi
来修复此问题(至少在经过测试的设备上),这会阻止IME以横向方向进入全屏模式。
最终解决方案(等待实施和测试)
EditText
旁边)添加了一个按钮,用于在NUMBER&amp;文字模式有关所尝试方法的详细信息,请参阅this discussion thread。
<强>截图强>
默认(NUMBER):
切换到TEXT :
答案 1 :(得分:2)
我同意它是一个InputType。如果您只想向用户显示数字,那么您可以将以下内容添加到编辑文本的xml文档中:
android:inputType="number"
但是,如果将其设置为数字,则用户必须输入一个数字。但您可以添加其他类型以及数字和电子邮件地址,例如:
android:inputType="number|textEmailAddress"
查看http://developer.android.com/reference/android/text/InputType.html了解更多选项。您还可以查看eclipse或android studio在&#34; inputType&#34;
下显示的内容答案 2 :(得分:0)
我相信您要设置编辑文本的InputType。
http://developer.android.com/reference/android/text/InputType.html
我不确定你会使用哪种,但你可能需要玩一下。
答案 3 :(得分:0)
执行此操作的唯一方法是设置EditText
的 inputType 。
如果要在onCreate()
(或自定义View
的构造函数内)中设置此属性,可以使用方法setRawInputType():
mEditText.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
否则,如果您需要在onCreate()
之后(或在自定义View
的构造函数之后)之后设置此属性,则可以使用方法{ {3}}:
mEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
显然,您还可以在 XML 级别指定属性:
android:inputType="number|numberDecimal"
您可以使用不同的标记来查找最佳组合过滤器。
答案 4 :(得分:0)
以编程方式可以对通常的流量进行一点调整。首先,您必须将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 with number keypad by default, but allowing alphabetic characters