最近的项目中需要输入字母,且环境有一些特殊的要求:

  • 不能跳出当前APP
  • 只需输入大写字母和数字

一般的第三方输入法都有跳出当前APP的路径,这是不允许存在的,机器7.0自带的键盘也非常的不好用,复杂而且不符合国人习惯.项目之前是用RecycleView在应用界面内实现输入数字,避免调起系统输入法来解决上面的这些问题的,但是现在需要输入字母,那个方案就不行了,而且占用较大的界面面积,改版后需要弹出键盘输入.势必要改了.

在之前的项目中因为有的第三方输入法在使用蓝牙设备输入的时候会自动转成拼音,导致输入错误,所以当时就做过一个键盘,是根据<Android InputMethodService|KeyboardView 自定义输入法和键盘 01>这个demo修改的.当时做得很简单没有遇到什么问题,大家跟着操作就好.但是这次的要求更复杂些,改的时候也遇到了一些问题,记录一下.

按键不够时如何让键盘铺满底部

全键盘的时候还好,但是做9键的时候遇到了因为按键不够,键盘不能铺满屏幕底部的问题.开始我用android:horizontalGap="32.3%p"这个属性来把按键撑开,看起来确实有点效果,但是1是很难调整,2是按键会比看起来的大,撑开的距离也是按键的范围,点击也是有响应的.后来通过修改键盘的测量尺寸解决:

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(screenWidth, getKeyboard().getHeight());
}

9键时9键不居中

默认的按键布局是从左起的,也没有发现什么控制gravity的方法.后来通过给每一个键的x加一个偏移量,实现整个9键的居中显示:

 mKeyboardNum = new Keyboard(context,R.xml.digit,0, screenWidth, ViewGroup.LayoutParams.WRAP_CONTENT);int addWidth = (int) (screenWidth * 0.33);for (Keyboard.Key key : mKeyboardNum.getKeys()) {key.x += addWidth;}setKeyboard(mKeyboardNum);

InputConnection如何清空当前的输入内容

键盘有做清空的功能,但是拿到InputConnection实例后,发现没有clear,remove之类名字的api可供调用清空,难道這么简单的功能也没提供?百度 inputconnection 清空也毫无结果,删除一个char的话调用的是boolean deleteSurroundingText(int beforeLength, int afterLength);那么多个呢?观察这个方法的注释:

     * @param beforeLength The number of characters before the cursor to be deleted, in code unit.*        If this is greater than the number of existing characters between the beginning of the*        text and the cursor, then this method does not fail but deletes all the characters in*        that range.* @param afterLength The number of characters after the cursor to be deleted, in code unit.*        If this is greater than the number of existing characters between the cursor and*        the end of the text, then this method does not fail but deletes all the characters in*        that range.* @return true on success, false if the input connection is no longer valid.*/boolean deleteSurroundingText(int beforeLength, int afterLength);

那么清空就很简单了.

ic.deleteSurroundingText(Integer.MAX_VALUE,Integer.MAX_VALUE);

转发EditorAction给EditText

要通过InputConnection$sendKeyEvent,当前焦点的EditText的OnEditorActionListener才能收到action.

 ic.sendKeyEvent(new KeyEvent(eventTime,eventTime,KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_ENTER,0,0,KeyCharacterMap.VIRTUAL_KEYBOARD,0,KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE | KeyEvent.FLAG_EDITOR_ACTION));

EditText禁用长按弹出复制菜单

长按菜单中会有分享,可能导致跳出当前app,所以要禁用掉.

mVB.etCode.customSelectionActionModeCallback = object : android.view.ActionMode.Callback {override fun onCreateActionMode(mode: android.view.ActionMode?, menu: Menu?): Boolean =falseoverride fun onPrepareActionMode(mode: android.view.ActionMode?, menu: Menu?): Boolean =falseoverride fun onActionItemClicked(mode: android.view.ActionMode?,item: MenuItem?): Boolean = falseoverride fun onDestroyActionMode(mode: android.view.ActionMode?) {}
}

把自己的键盘设为系统默认

即使当前系统以及切换到我们的键盘,但是如果我们的键盘升级重装的话,默认输入法又会被恢复为默认是系统键盘,如何自动的再切到我们的键盘呢?通过Settings.Secure.getString(context.contentResolver, Settings.Secure.DEFAULT_INPUT_METHOD)可以获取到当前的默认输入法ID.而且还有一个方法Settings.Secure.putString(context.contentResolver, Settings.Secure.DEFAULT_INPUT_METHOD,SmInputMethod.INPUT_METHOD_ID)可以设置默认输入法的ID,是不是我们调用这个方法就可以了呢?当然没有这么简单,这个操作需要android.permission.WRITE_SECURE_SETTINGS权限,需要是系统APP才能调用,还有没有其他办法呢?如果机器是root了的话,是可以的.

 val execCmd = ShellUtils.execCmd("settings put secure default_input_method ${MyInputMethod.INPUT_METHOD_ID}",true,true)LogUtils.d(TAG,execCmd?.result)val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManagerval string = Settings.Secure.getString(contentResolver,Settings.Secure.DEFAULT_INPUT_METHOD)LogUtils.d(TAG, "cur ime: $string")val find = imm.enabledInputMethodList.find { it.id == SmInputMethod.INPUT_METHOD_ID }if (find == null) {val keyBordIntent = Intent()keyBordIntent.action = Settings.ACTION_INPUT_METHOD_SETTINGSRxActivityResult.on(this@RelaunchActivity).startIntent(keyBordIntent).subscribe { result ->result.targetUI().apply {imm.showInputMethodPicker()}}}

这样就可以了,关于修改secure Settings,我还发现一种方法.

private fun setDefaultInputMethod() {try {val pathname = "/data/system/users/0/settings_secure.xml"ztlManager.execRootCmdSilent("chmod 777 $pathname")val localFile = File(filesDir, "settings_secure.xml")ztlManager.execRootCmdSilent("cp -f $pathname ${localFile.absolutePath}")ztlManager.execRootCmdSilent("chmod 777 ${localFile.absolutePath}")val factory = DocumentBuilderFactory.newInstance()val builder = factory.newDocumentBuilder()val doc = builder.parse(localFile)val root = doc.getElementsByTagName("settings")val item = root.item(0)val childNodes = item.childNodesloopOut@ for (i in 0 until childNodes.length) {val node = childNodes.item(i)val attributes = node.attributes ?: continue@loopOutfor (j in 0 until attributes.length) {val item1 = attributes.item(j)if (item1.nodeValue == Settings.Secure.DEFAULT_INPUT_METHOD) {val item2 = attributes.item(j + 1)item2.nodeValue = SmInputMethod.INPUT_METHOD_IDval item3 = attributes.item(j + 2)item3.nodeValue = packageNameLogUtils.d(TAG, "find target ${item2.toString()}")break@loopOut}}}val tFactory = TransformerFactory.newInstance();// 将内存中的Dom保存到文件val transformer = tFactory.newTransformer();
//            // 设置输出的xml的格式,utf-8transformer.setOutputProperty("encoding", "utf-8");val source = DOMSource(doc)
//            //xml的存放位置val src = StreamResult(localFile)transformer.transform(source, src)ztlManager.execRootCmdSilent("chmod 777 $pathname")ztlManager.execRootCmdSilent("rm -f $pathname")val execCmd =ShellUtils.execCmd("cp -f ${localFile.absolutePath} $pathname", true, true)LogUtils.d(TAG,  execCmd?.errorMsg)
//            ztlManager.execRootCmdSilent("cp -f ${localFile.absolutePath} $pathname")} catch (e: Exception) {e.printStackTrace()}}

发现可以settings put secure default_input_method ${MyInputMethod.INPUT_METHOD_ID}之前我是這么实现的,好像有用.也算一个方法吧,对于不支持直接adb shell命令的内容修改,还是可以尝试的.

综上遇到的几个小点.

Android自定义键盘的几个小点相关推荐

  1. android自定义数字键盘和字母键盘,Android自定义键盘的实现(数字键盘和字母键盘)...

    Android自定义键盘的实现(数字键盘和字母键盘) 发布时间:2020-09-04 03:18:48 来源:脚本之家 阅读:100 作者:浪淘沙xud 在项目中,产品对于输入方式会有特殊的要求,需要 ...

  2. Android 自定义键盘 随机键盘

    之前上传的另外一个自定义键盘,并没有实现键盘弹出的时候,布局向上自动调整.(网络上所有的自定义键盘都没有添加自适应的功能,而且布局没这么好看,上一个例子资源链接为:http://download.cs ...

  3. android 键盘开发demo,Android自定义键盘之中文键盘demo

    [实例简介] Android自定义键盘之中文键盘demo,演示了汉字键盘的实现方法.更详细描述见相关博客. [实例截图] [核心代码] keydemo └── keydemo ├── AndroidM ...

  4. 关于android自定义键盘

    因为百度里面搜索android自定义键盘内容很少,所以就将我在github上找到的好点的键盘(keyboard)源码分享出来: (因为我在源码上修改了,所以图片是我源码修改之后的图片,大家可以到git ...

  5. android自定义键盘遮挡,Android软键盘遮挡的四种完美解决方案

    一.问题概述 在编辑框输入内容时会弹出软键盘,而手机屏幕区域有限往往会遮住输入界面,我们先看一下问题效果图: 输入用户名和密码时,系统会弹出键盘,造成系统键盘会挡住文本框的问题,如图所示: 输入密码时 ...

  6. android 自定义数字软键盘,Android自定义键盘的实现(数字键盘和字母键盘)

    在项目中,产品对于输入方式会有特殊的要求,需要对输入方式增加特定的限制,这就需要采用自定义键盘.本文主要讲述数字键盘和字母键盘的自定义实现. 自定义键盘的实现步骤如下: 自定义CustomKeyboa ...

  7. Android自定义键盘详解、自定义输入法简介

    概述 Android中有两个系统类是用来实现键盘的,分别是Keyboard和KeyboardView. Keyboard有个内部类Key,用于记录每个键的信息,如code.width.height等. ...

  8. Android的自定义键盘颜色,android自定义键盘(解决弹出提示的字体颜色问题)

    最近准备要做一个项目,需要用到自定义小键盘来确保安全,而且还需要精确获得用户点击键盘时的落点位置.力度.指尖接触屏幕的面积等参数. 在写自定义键盘的时 最近准备要做一个项目,需要用到自定义小键盘来确保 ...

  9. android 自定义键盘字体大小,android.inputmethodservice.KeyboardView 自定义键盘 字体大小设置...

    KeyboardView 设置自定义键盘上文本的属性,其中字体的设置用:android:keyTextSize    android:labelTextSize 即可实现!! 亲测! android: ...

最新文章

  1. python中的协程(二)
  2. 如何获取文件的完整路径?
  3. python代码有时候在命令行下和Python Shell中执行的结果不一样?
  4. airflow零基础入门
  5. PHP读取数据库表显示到前台
  6. run sequence between odata request and controller init
  7. 解决android sdk 无法更新
  8. Illustrator中文版教程,如何在 Illustrator 中使用颜色混合器创建色板?
  9. 为什么要使用多层开发?
  10. 液压伺服控制系统设计
  11. 计算机硬盘的存储时间,存储访问时间
  12. 如何使用浏览器的网页全文翻译工具
  13. 7-161 双曲余弦函数(*)
  14. 三分钟带你玩转PDF文件签名
  15. RT_Thread_空闲线程
  16. Mybatis的where标签,还有这么多知识点
  17. 基于R语言的聚类分析(k-means,层次聚类)
  18. 使用IDEA工具查看Java类层次结构关系图
  19. C语言简单的键盘玩扫雷小游戏(完结)
  20. SpringCloud持续集成项目部署

热门文章

  1. 【智驾深谈】一张图看清自动驾驶产业
  2. 数字经济之新零售行动派:鸡毛换糖走向数智化
  3. linux 内存清理释放命令
  4. 80后的回忆·少年篇
  5. ArcEngine IPageLayout 添加经纬网和公里网
  6. 样本方差公式推导--为什么样本方差的分母是n-1
  7. 基于Arduino项目案例
  8. 自己搭建网站一个月多少钱?
  9. SwitchHosts 模拟本地域名解析访问
  10. wxMEdit 新增德文翻译