A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

1黑马币
本帖最后由 xiaoqing 于 2015-12-20 12:32 编辑

监听EditText的状态,能够做关联词联想等有用的功能。今天就来看看深圳问答网的技术老师来详细说说这个问题:




学生问题:老师,请问如何监听EditText的输入状态?
答:

设置默认输入法
  有时候为了提高用户体验,在弹出输入法时需要设置默认的输入状态,比如单词应用弹出输入法时,输入法最好是在英文输入状态下。如果是字典应用,弹出输入法时最好是在中文输入状态下,Android并没有提供设置默认的输入状态的接口,但我们可以通过如下方法一样能够达到想要的效果:
        默认中文:
  1. mEditText.setInputType(EditorInfo.TYPE_CLASS_TEXT);
复制代码

     默认英文:
  1. mEditText.setInputType(EditorInfo.TYPE_TEXT_VARIATION_URI);
复制代码
打开和关闭输入法
  手动控制输入法的开关状态也能提升用户体验,比如:
  • 有的搜索框会有一个清除按钮,点击清除按钮时就应该弹出输入法,因为用户清除搜索内容的目的多数时候是需要输入新的内容;
  • 执行搜索时应该隐藏输入法,因为显示输入法时会遮挡搜索结果,用户体验不太好;
  • 闹钟来时或者有其它window弹出时应该隐藏输入法,因为输入法也是window,如果不隐藏可能导致输入法遮挡住了其它window等用户体验不太友好的问题。

  打开输入法:
  1. private void open(Context context, View editText){
  2.                     InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
  3.                     inputMethodManager.showSoftInput(editText, 0);
  4.                 }
复制代码
监听EditText的输入状态
  • 类似新浪微博,在输入内容时会提示还可以输入多少字;
  • 有的搜索引擎,输入内容时实时显示搜索结果;
  • 有的输入框有输入长度限制,输入内容超过长度限制时弹出提示信息。
    上面这些都可以通过监听EditText的输入状态来实现,具体实现方式如下:
    1. mInputEditTxt.addTextChangedListener(new TextWatcher() {        @Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {

    2.         }        @Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {
    3.             System.out.println("监听EditText输入内容的变化,在这里可以监听输入内容的长度。");
    4.         }        @Overridepublic void afterTextChanged(Editable s) {
    5.             System.out.println("这里可以实现所输即所得,用户输入的同时可以立即在这里根据输入内容执行操作,显示搜索结果!");
    6.         }
    7.     });
    复制代码
    监听输入法中的回车按钮比如搜狗输入法的右下角有一个回车按钮,我们希望用户点击它时也执行确认功能,可以通过监听EditText的按键点击事件来实现:
    1. /**
    2.              * 监听输入法按键
    3.              *
    4.              * */
    5.             mInputEditTxt.setOnKeyListener(new OnKeyListener() {
    6.                 @Override        public boolean onKey(View v, int keyCode, KeyEvent event) {            if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
    7.                         System.out.println("手指弹起时执行确认功能");                return true;
    8.                     }            return false;
    9.                 }
    10.             });
    复制代码

    改变输入法中回车按钮的显示内容
      如果回车按钮是执行搜索功能,则回车按钮上显示"搜索",如果是执行发送功能,则显示"发送",如果是下一步,则显示"下一步"。
      实现这个功能需要调用EditText的setImeOptions方法:

  1. /**** IME_ACTION_SEARCH 搜索* IME_ACTION_SEND 发送* IME_ACTION_NEXT 下一步* IME_ACTION_DONE 完成
  2.                 */
  3.                 mInputEditTxt.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
复制代码
限制输入内容
  有时候我们根本就不想用户输入一些杂七杂八的内容,因为这需要程序针对输入的内容做各种处理,如果处理不当还会有好多不可预见的问题,索性在输入内容时就禁止用户输入一些非法字符,这可以通过下面的方式实现,新建一个类InputTxtFilter:
  1. public class InputTxtFilter {
  2.         public static final int INPUT_TYPE_EN = 0x01;
  3.         public static final int INPUT_TYPE_CH = 0x02;
  4.         private static final String[] SPELL = new String[] { "a", "b", "c", "d",
  5.                         "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q",
  6.                         "r", "s", "t", "u", "v", "w", "x", "y", "z", "ā", "á", "ǎ", "à",
  7.                         "ō", "ó", "ǒ", "ò", "ē", "é", "ě", "è", "ī", "í", "ǐ", "ì", "ū",
  8.                         "ú", "ǔ", "ù", "ǖ", "ǘ", "ǚ", "ǜ", "ü" };
  9.         private static char[] chineseParam = new char[] { '」', ',', '。', '?', '…',
  10.                         ':', '~', '【', '#', '、', '%', '*', '&', '$', '(', '‘', '’', '“',
  11.                         '”', '『', '〔', '{', '【', '¥', '£', '‖', '〖', '《', '「', '》', '〗',
  12.                         '】', '}', '〕', '』', '”', ')', '!', ';', '—' };

  13.         private InputTxtFilter() {

  14.         }

  15.         public static void inputFilter(final Context context,
  16.                         final EditText editText, final int type, final int inputLimit) {
  17.                 InputFilter[] filters = new InputFilter[1];
  18.                 filters[0] = new InputFilter.LengthFilter(inputLimit) {
  19.                         public CharSequence filter(CharSequence source, int start, int end,
  20.                                         Spanned dest, int dstart, int dend) {
  21.                                 boolean isRightCharater = false;
  22.                                 if (type == INPUT_TYPE_EN) {
  23.                                         isRightCharater = isLetter(source.toString());
  24.                                 } else if (type == INPUT_TYPE_CH) {
  25.                                         isRightCharater = isChineseWord(source.toString());
  26.                                 }
  27.                                 if (!isRightCharater || dest.toString().length() >= inputLimit) {
  28.                                         return "";
  29.                                 }
  30.                                 return source;
  31.                         }
  32.                 };
  33.                 editText.setFilters(filters);
  34.         }

  35.         /**
  36.          * 检测String是否全是中文
  37.          *
  38.          */
  39.         public static boolean isChineseWord(String name) {
  40.                 boolean res = true;
  41.                 char[] cTemp = name.toCharArray();
  42.                 for (int i = 0; i < name.length(); i++) {
  43.                         if (!isChinese(cTemp[i])) {
  44.                                 res = false;
  45.                                 break;
  46.                         }
  47.                 }
  48.                 return res;
  49.         }

  50.         /**
  51.          * 是否为英文字母
  52.          *
  53.          * */
  54.         public static boolean isLetter(String inputStr) {
  55.                 char[] inputArray = inputStr.toCharArray();
  56.                 List<String> spellList = Arrays.asList(SPELL);
  57.                 for (char input : inputArray) {
  58.                         if (!spellList.contains(input + "")) {
  59.                                 return false;
  60.                         }
  61.                 }
  62.                 return true;
  63.         }

  64.         /**
  65.          * 判定输入汉字
  66.          *
  67.          * @param c
  68.          */
  69.         public static boolean isChinese(char c) {
  70.                 for (char param : chineseParam) {
  71.                         if (param == c) {
  72.                                 return false;
  73.                         }
  74.                 }

  75.                 Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
  76.                 if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
  77.                                 || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
  78.                                 || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
  79.                                 || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
  80.                                 || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
  81.                                 || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
  82.                         return true;
  83.                 }
  84.                 return false;
  85.         }
  86. }
复制代码

在初始化EditText时,调用InputTxtFilter的inputFilter方法,传入输入长度限制、输入内容的类型限制等即可,eg:
  1. InputTxtFilter.inputFilter(this, mInputEditTxt, InputTxtFilter.INPUT_TYPE_EN, 5);
复制代码

屏蔽EditText的复制、粘贴功能
  在低版本的Android SDK中,如果对EditText的输入长度有限制时,长按EditText并将选中的内容拖动到EditText输入框中,如果这时候的长度超过了EditText的输入长度限制,程序会直接崩溃掉,在高版本的Android SDK中这个问题已经改了,如果出现上面的情况会直接清空输入框中的内容,为了避免这种讨厌的问题,我们可以屏蔽EditText的复制和粘贴功能,只需要屏蔽EditText的长按响应即可:
  1. /**
  2.      * 屏蔽复制、粘贴功能
  3.      * */
  4.     mInputEditTxt.setCustomSelectionActionModeCallback(new ActionMode.Callback() {        public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {            return false;
  5.         }        public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {            return false;
  6.         }        public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {            return false;
  7.         }        @Overridepublic void onDestroyActionMode(ActionMode mode) {

  8.         }
  9.     });

  10.     mInputEditTxt.setLongClickable(false);
复制代码



深圳校区除了全国独有问答网,就业老师面试服务,还有更多神秘惊喜等着你,咨询热线:0755-66689855

2 个回复

正序浏览
确实不错,其实只是想来这里找一些有用的东西,收获挺大的.gg才知道这里有黑马老师团队提供的有些资源,谢谢了
回复 使用道具 举报
监听文本改变的状态
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马