MC *_*ror 13 android android-keypad android-softkeyboard android-inputtype
我有一个EditText组件,当然,如果你点击它,会显示Android键盘,允许用户输入文本.据我所知,所有Android软件键盘都有(至少)字母模式(ABC)和符号模式(?123).他们的默认视图是字母模式.
现在,当EditText单击组件时显示键盘时,我希望默认显示符号模式.用户仍然可以切换到字母模式.

有没有办法实现这一目标?如果有,怎么样?
Vik*_*ram 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)> = 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.
问题:
如您所知,这不是一个真正的解决方案.如果用户back在TEXT模式下关闭键盘(使用按钮),键盘将在再次打开时保持TEXT模式.要进入NUMBER模式,用户必须单击NUM.此外,在TEXT模式下,用户将看到NUM操作以及?123选项.这不会破坏任何东西,但确实会从UX中消失.
?123由于上面列出的原因,我们无法在TEXT模式下显示任何内容.但是,我们可以尝试确保键盘始终以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,这似乎工作.将需要更多测试.
我真的希望有人可以提出一个比这更好,更强大的解决方案 - 或者修改我的解决方法,使它看起来不像一个.
摘要
手头的任务是提供围绕现有输入法引擎(IME)在NUMBER和TEXT输入模式之间切换的功能.第一种方法是imeActionLabel & imeActionId在切换机制中使用.这种方法适用于谷歌的键盘(这是imeActionLabel),但三星的imeActionLabel失败 - 未能以肖像显示(没有提取).可能的解决方法是在应用程序自己的UI中包含切换按钮.
即使使用Google的键盘,在输入字母后模式切换回NUMBER时,字母(文本)也无法显示.通过使用标志flagNoExtractUi来修复此问题(至少在测试的设备上),该标志阻止IME以横向方向进入全屏模式.
最终解决方案(待执行和测试)
EditText),用于在NUMBER和TEXT模式之间切换有关所尝试方法的更多信息,请参阅此讨论主题.
截图
默认(NUMBER):

切换到TEXT:

| 归档时间: | 
 | 
| 查看次数: | 9163 次 | 
| 最近记录: |