zoukankan      html  css  js  c++  java
  • Android 开发之拦截EditText的输入内容,定制输入内容

    1.EditText作为一个比较成熟的View,在Android的应用开发中得到极为广泛的使用。在某些特殊情况下,我们可能需要定制EditText的输入内容,

    只允许指定功能的输入,例如输入一个”ddd:mm:ssssss“格式的度分秒角度。

    一些错误的思路有:

    (1)OnKeyListener,实现EditText的OnKeyListener并不能拦截EditText的输入,OnKeyListener只能够监听到一些按物理键事件,例如菜单键、返回键、音量键等,

    而输入法作为一个单独的进程,EditText与输入法的通讯显然是OnKeyListener所无能为力的;

    (2)TextWatcher,相信很多同志做这个功能的第一反应都是使用TextWatcher,因为TextWatcher可以监听到EditText输入前后内容的变化,但那也只是监听到而已

    ,它并没有办法真正拦截到输入,而只是在某一字符输入发生后,对EditText做一个事后的处理。典型的例子如下,假设我监听到了”s“的输入,但实际上我是不允许”s“输入的,那

    么我在TextWatcher中监听到”s“输入了以后,重新设置EditText的内容。但这样做的恶果就是重设EditText的内容后,又会回调TextWatcher的那几个方法,造成死循环。当然您可以

    设置一个标志位来停止这个循环,但麻烦不止于此。因为你是先让字符输入,然后再手动把它删除,那么这其中涉及到的光标位置调整,将无穷无尽……

    2.讲述了上面两种典型的错误之后(事实上也是LZ曾经犯过的),介绍一下LZ对于真正EidtText输入拦截的实现。

    既然系统给的接口都无法实现,那么势必要通过源码来解决问题了。EditText是继承与TextView的,TextView的源码量非常大,一个个函数看

    肯定不现实,那么按关键字搜吧,搜索”input“可以查到”onCreateInputConnection“这个方法 ,字面意思创建与输入法的通信,返回的对象是InputConnection,

    很有可能就是它了,InputConnectionWrapper 实现了InputConnection, 而这个类的实现方法中有两个极为可靠的方法,commitText, sendKeyEvent,字面意思提交文本

    和按键事件。看到这里,想必思路也差不多了:

    (1)重载onCreateInputConnection方法,它需要返回一个InputConnection对象;

    (2)继承于InputConnectionWrapper, 实现自己的InputConnection 并且在onCreateInputConnection中返回。

    (3)在自定义的InputConnectionWrapper类中,实现输入法输入和按键时间的拦截。

    (4)拦截条件:在commitText方法中,如果执行父类的 commitText(即super.commitText(text, newCursorPosition))那么表示不拦截,如果返回false则表示拦截,

    输入法的字符串则无法传送到EditText。在sendKeyEvent中,如果执行父类的sendKeyEvent(即super.sendKeyEvent(event))那么表示不拦截,如果返回false表示拦截。

    3.至此,EditText的定制输入的最总要环节,拦截EditText与输入法的通讯已经成功实现,接下来的就是根据你的定制规则去重载你的commitText和sendKeyEvent方法吧。

    几个重要的方法,

    设置光标位置:setSelection(cursor - 1, cursor -1);

    删除光标坐标0(m)个到光标右边1(n)个字符:deleteSurroundingText(0, 1);

    此外,不同的输入法的KeyEvent方法可能有些不同,你需要查看SoftKeyboard示例源码来对你的应用进行调试,以使它能够兼容主流的输入法。

  • 相关阅读:
    Linux recordmydesktop
    linux music play
    linux config NDK
    linux install wireshark
    Linux config cocos
    45 线程池都有哪些状态?
    44 创建线程池有哪几种方式?
    final 不能修饰抽象类和接口
    43 线程的 run() 和 start() 有什么区别?
    42 notify()和 notifyAll()有什么区别?
  • 原文地址:https://www.cnblogs.com/yiludugufei/p/4578977.html
Copyright © 2011-2022 走看看