问题描述
我有一个的EditText
组件,当然,如果你点击它,在Android键盘显示,允许用户输入文本。据我所知,所有的Android软件键盘有(至少)一个字母模式(农行
)和一个符号模式(?123
)。它们的默认视图是字母模式。
I have a EditText
component, and, of course, if you click on it, the Android keypad is shown, allowing the user to input text. As far as I know, all Android software keyboards have (at least) a letter mode (ABC
) and a symbols mode (?123
). Their default view is the letter mode.
现在,当的EditText
成分被点击时键盘显示,我想符号模式在默认情况下显示。用户将仍然能够切换到字母模式。
Now when the keypad is shown when the EditText
component is clicked, I want the symbols mode to be shown by default. The user will still be able to switch to the letter mode.
有没有办法来实现这一目标?如果是的话,怎么办?
Is there a way to achieve that? If yes, how?
推荐答案
我张贴这一点,因为我不认为任何答案真正解决问题。在问题的截图不对应于一个特定InputType的默认状态。因此,开关InputTypes不会给你从截图中的布局。
I'm posting this because I don't think any of the answers actually address the question. The screenshot in the question does not correspond to a particular InputType's default state. So, switching InputTypes will not give you the layout from the screenshot.
(根据我的研究...)
(based on my research...)
支持符号输入不受任何合同约束。人们可以创建自己的 InputMethod
的时候非常好离开的符号了。或者,他们可以添加分页支持,提供对符号的100S。可以这样约束合同?有可能。但是,这不是在present
Support for symbol input is not governed by any contract. One can very well leave symbols out when creating their own InputMethod
. OR, they can add pagination support to provide access to 100s of symbols. Can this be bound by a contract? May be. But, it isn't at present.
输入法框架不允许客户端与放大器之间的直接沟通;输入法。所有通信都发生或者通过 InputMethodManager
,或通过 InputConnection
- 单向通道。切换到使用符号123
然而,一个内部事件? - 没有一个确定的状态/动作的。客户端应用程序不能的开关将其的。有没有公共(或隐藏)API来实现这一目标。
Input method framework does not allow direct communication between the client & the IME. All communication happens either through the InputMethodManager
or through InputConnection
- one-way channel. Switching to symbols using ?123
is however, an internal event - not a defined state/action. Client applications cannot switch to it. There's no public(or hidden) API to make this happen.
InputType
表示完全不同的东西,以一种输入法。不知道为什么每个人都在推荐其使用。 您当然可以找到一个特定的 InputType
提供大部分所需按键。但是,这是不一样的显示[和] Android键盘的符号模式默认情况下。
InputType
indicates something entirely different to an IME. Not sure why everyone is recommending its use. You may of course find that a particular InputType
provides most of the required keys. But that isn't the same as show[ing] Android keyboard with symbols mode by default.
可能的解决方法
我们将创建一个自定义的的EditText
。我们不必。它只会把一切都在一个地方,并拯救我们从复制粘贴的噩梦。
We'll create a custom EditText
. We don't have to. It'll just keep everything in one place, and save us from copy-paste nightmare.
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 /价值/ integers.xml
并添加:
Next, we need to define definedActionId
. Open or create res/values/integers.xml
and add:
<integer name="definedActionId">-100</integer>
-100
是一个任意值。我检查 EditorInfo
和actionIds( IME_ACTION_XXXX
)分别为> = 0 -100
似乎是个不错的人选。
-100
is an arbitrary value. I checked EditorInfo
and the actionIds (IME_ACTION_XXXX
) were >= 0. -100
seems like a good candidate.
在XML中,你的布局将是这样的:
In xml, your layout will look like:
<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将推出在数字模式。相反,复选标记图标,它会显示农行
。在点击,我们截取了actionId和NUMBER和文本输入之间切换。我们使用 setInputType(...)
,因为它不仅更新 InputType
,它也重新启动IME与的变化。 setRawInputType(...)
只更新 InputType
。
There's not much to explain. IME will launch in NUMBER mode. Instead of a checkmark icon, it'll display ABC
. On click, we intercept the actionId and toggle between NUMBER and TEXT input. We're using setInputType(...)
because it not only updates the InputType
, it also restarts the IME with changes. setRawInputType(...)
only updates the InputType
.
问题
正如你所知道的,这是不是一个真正的解决方案。如果用户关闭键盘(使用返回
键)在文本模式下,的的键盘会,当他们打开它的再次停留在文本模式。要进入数字模式,用户必须点击 NUM
。此外,在文本模式下,用户将看到 NUM
作为动作,以及?123
选项。这不的破解的任何东西,但它从UX带走。
As you can tell, this isn't really a solution. If the user closes the keyboard(using the back
button) in TEXT mode, the keyboard will remain in the TEXT mode when they open it again. To go to the NUMBER mode, user will have to click NUM
. Also, in TEXT mode, user will see NUM
as the action, along with ?123
option. This doesn't break anything, but does take away from the UX.
我们不能做任何事情?123
显示在文本模式下上面列出的原因。但是,我们可以尝试以确保键盘的总是的在数字模式打开。我将提供如何,我们会做一个粗略的草图。它不是直接的,因为我们(开发商)不知道这种键盘关闭或打开事件。更新 CusEditText
:
We can't do anything about ?123
showing in TEXT mode for reasons listed above. But, we can try to make sure that the keyboard always opens in the NUMBER mode. I'll provide a rough sketch of how we'll do that. Its not straight-forward since we (developers) are not privy to events such as keyboard closing or opening. Updated 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();
}
}
}
此外,code是不言自明的。我们创建了一个 InputConnectionWrapper
,并听取了 finishComposingText()
回调。如果我们手动文本
和号
之间的转换,我们使用了一个标志,因为 finishComposingText( )
将自动被调用。否则,我们检查,如果输入类型设置为文本
键,将其更改为号
。我不知道,如果 finishComposingText()
是正确的方法,除preting键盘关闭/打开。在API 21,香草Android的测试,这似乎工作。更多的试验是必需的。
Again, code is self-explanatory. We create a InputConnectionWrapper
and listen for the finishComposingText()
callback. If we're manually switching between TEXT
and NUMBER
, we use a flag since finishComposingText()
will automatically be called. Else, we check if input type is set to TEXT
and change it to NUMBER
. I am not sure if finishComposingText()
is the right method for interpreting keyboard closing/opening. Testing on API 21, vanilla android, this seems to work. More tests will be required.
我真的希望有人能拿出一个更好的,更强大的解决方案比这个 - 或者修改我的解决方法,以便它看起来并不像一个
I really hope someone can come up with a better, more robust solution than this - or modify my workaround so that it doesn't look like one.
摘要
手头任务是提供的数字与功放之间切换的功能;文字输入模式围绕现有的输入法引擎(输入法)。第一种方法是使用 imeActionLabel和放大器; imeActionId
在切换机制。这种做法与谷歌的键盘运作良好(这是imeActionLabel ),但未能与三星的 - <$c$c>imeActionLabel$c$c>没有露面的肖像(不提取)。可能的解决办法是,包括在应用程序的自己的UI切换按钮。
Task at hand is to provide functionality of switching between NUMBER & TEXT input modes around existing Input Method Engines (IMEs). The first approach was to use imeActionLabel & imeActionId
in the switching mechanism. This approach worked well with Google's keyboard (this is the imeActionLabel), but failed with Samsung's - imeActionLabel
failed to show up in portrait (without extract). Possible workaround is to include the toggle button in the app's own UI.
即使谷歌的键盘,字母(文字)无法显示在模式切换回数输入字母后。此问题已修复(至少在测试设备)使用标志 flagNoExtractUi
其prevents从横向进入全屏模式的输入法。
Even with Google's keyboard, the letters (text) fail to show up when the mode switches back to NUMBER after inputting letters. This problem was fixed (at least on tested devices) by using flag flagNoExtractUi
which prevents the IME from entering fullscreen mode in landscape orientation.
最终的解决方案(等待执行与测试)
- 在该输入法开始在数字输入模式(95%的用例涉及数字输入)
- 一个按钮添加到应用程序的用户界面(旁边的
的EditText
)的数字与功放之间切换; TEXT模式 - 用户可以从号码切换到文本没有任何限制。切换从文本到多少回要求,没有字母已被添加。
- InputType是键盘收盘与功放之间preserved;重新开放。例:如果用户切换到文本模式并关闭键盘时,它会在文本模式下打开。该InputType是的没有的复位。
- The IME starts in the NUMBER input mode (95% use-cases involve number input)
- A button is added to app's UI (next to the
EditText
) for switching between NUMBER & TEXT mode - User can switch from NUMBER to TEXT without any restrictions. Switching back from TEXT to NUMBER requires that no alphabets have been added.
- InputType is preserved between keyboard closing & reopening. Example: If the user switches to TEXT mode and closes the keyboard, it will open in the TEXT mode. The InputType is not reset.
有关该方法的详细信息试图,参阅这个话题
For more information about the approaches tried, refer to this discussion thread.
截图
默认(NUMBER)
切换到文本
这篇关于如何显示Android键盘的符号模式在默认情况下?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!