- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个 EditText
组件,当然,如果您单击它,则会显示 Android 键盘,允许用户输入文本。据我所知,所有 Android 软件键盘(至少)都有字母模式( ABC
)和符号模式( ?123
)。他们的默认 View 是字母模式。
现在当键盘显示时 EditText
单击组件,我希望默认显示符号模式。用户仍然可以切换到字母模式。
有没有办法实现这一目标?如果是,如何?
最佳答案
我发布这个是因为我认为任何答案都没有真正解决这个问题。问题中的屏幕截图与特定 InputType 的默认状态不对应。因此,切换 InputTypes 不会为您提供屏幕截图中的布局。
(根据我的研究...)
对符号输入的支持不受任何合约的约束。在创建自己的符号时,可以很好地忽略符号 InputMethod
.或者,他们可以添加分页支持以提供对数百个符号的访问。这可以受契约(Contract)约束吗?也许。但是,目前不是。
输入法框架不允许客户端和 IME 之间的直接通信。所有通信都通过 InputMethodManager
进行。或通过 InputConnection
— 单向 channel 。使用 ?123
切换到符号然而,是一个内部事件——不是一个定义的状态/ Action 。客户端应用程序无法切换到它。没有公共(public)(或隐藏)API 来实现这一点。InputType
表示与 IME 完全不同的东西。不知道为什么每个人都推荐使用它。 您当然可能会发现某个特定的 InputType
提供大部分所需的 key .但这与 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
似乎是一个不错的候选人。
<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 模式。要进入 NUMBER 模式,用户必须点击
NUM
.此外,在文本模式下,用户将看到
NUM
作为行动,随着
?123
选项。这不会破坏任何东西,但会影响用户体验。
?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、vanilla android 上测试,这似乎有效。将需要更多的测试。
imeActionLabel & imeActionId
在切换机制中。这种方法适用于 Google 的键盘 (
this is the imeActionLabel ),但不适用于三星的 -
imeActionLabel
failed to show up in portrait (没有
extract )。可能的解决方法是在应用程序自己的 UI 中包含切换按钮。
flagNoExtractUi
修复(至少在经过测试的设备上)这可以防止 IME 以横向方式进入全屏模式。
EditText
旁边)用于在 NUMBER 和 TEXT 模式之间切换 关于android - 默认情况下如何以符号模式显示Android键盘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25219855/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!