歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android字數限制的EditText實現方案研究

Android字數限制的EditText實現方案研究

日期:2017/3/1 10:07:16   编辑:Linux編程

在Android應用開發中,有時需要實現有字數限制的EditText,首先來分析下市面上存在的類似實現方案吧,好有個感性的認識。

【方案一:騰訊微博】

每個中文字符算一個字數,每兩個英文字符算一個字數,當用戶輸入內容時,實時顯示剩余的字數,當超出字數限制時,剩余字數顯示為負數,但此時用戶仍然可以繼續在EditText中輸入內容,直到用戶點擊菜單中的“發送”按鈕時,才會彈出對話框或者Toast顯示用戶輸入的字數超標,如下圖所示:

這個方案實現起來很簡單,只需要給EditText設置TextWatcher監聽器,然後判斷輸入的是中文字符還是英文字符,實時更新剩余輸入字數顯示即可,不需要限制EditText的輸入。

【方案二:百度旅游】

中英文字符都算一個字數,當用戶輸入內容時,實時顯示剩余的字數,當超出字數限制時,剩余字數顯示為0,不會出現負數的情況,這時EditText再也不接收用戶輸入的任何內容了。

這個方案由於中英文都占一個字數,因此可以直接給EditText設置InputFilter.LengthFilter,這時LengthFilter會自動幫EditText限制用戶輸入的內容;再給EditText設置TextWatcher監聽器,就可以實時更新剩余字數了。

本文綜合上面兩個方案,給出【方案三】,每個中文字符算一個字數,每兩個英文字符算一個字數,當用戶輸入內容時,實時顯示剩余的字數,當超出字數限制時,剩余字數顯示為0,不會出現負數的情況,這時EditText再也不接收用戶輸入的任何內容了。方案三可用於app需要集成第三方sns分享功能,且必須自己實現分享界面的情況。由於中英文所占的字數不一樣,就不能使用LengthFilter來限制用戶再EditText中輸入內容(因為在用戶完成內容輸入之前,是不知道要給lengthFilter設置的最大值的)。因此只能在TextWatcher中做些手腳了。方案三界面如下:

整個功能的核心實現都在EditText的TextWatcher監聽器裡面的afterTextChanged回調函數中。代碼如下所示:

  1. package com.hust.demo;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.text.Editable;
  5. import android.text.TextWatcher;
  6. import android.widget.EditText;
  7. import android.widget.TextView;
  8. publicclass MainActivity extends Activity {
  9. private EditText mEditText = null;
  10. private TextView mTextView = null;
  11. privatestaticfinalint MAX_COUNT = 140;
  12. @Override
  13. protectedvoid onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.main);
  16. mEditText = (EditText) findViewById(R.id.content);
  17. mEditText.addTextChangedListener(mTextWatcher);
  18. mEditText.setSelection(mEditText.length()); // 將光標移動最後一個字符後面
  19. mTextView = (TextView) findViewById(R.id.count);
  20. setLeftCount();
  21. }
  22. private TextWatcher mTextWatcher = new TextWatcher() {
  23. privateint editStart;
  24. privateint editEnd;
  25. publicvoid afterTextChanged(Editable s) {
  26. editStart = mEditText.getSelectionStart();
  27. editEnd = mEditText.getSelectionEnd();
  28. // 先去掉監聽器,否則會出現棧溢出
  29. mEditText.removeTextChangedListener(mTextWatcher);
  30. // 注意這裡只能每次都對整個EditText的內容求長度,不能對刪除的單個字符求長度
  31. // 因為是中英文混合,單個字符而言,calculateLength函數都會返回1
  32. while (calculateLength(s.toString()) > MAX_COUNT) { // 當輸入字符個數超過限制的大小時,進行截斷操作
  33. s.delete(editStart - 1, editEnd);
  34. editStart--;
  35. editEnd--;
  36. }
  37. mEditText.setText(s);
  38. mEditText.setSelection(editStart);
  39. // 恢復監聽器
  40. mEditText.addTextChangedListener(mTextWatcher);
  41. setLeftCount();
  42. }
  43. publicvoid beforeTextChanged(CharSequence s, int start, int count,
  44. int after) {
  45. }
  46. publicvoid onTextChanged(CharSequence s, int start, int before,
  47. int count) {
  48. }
  49. };
  50. /**
  51. * 計算分享內容的字數,一個漢字=兩個英文字母,一個中文標點=兩個英文標點 注意:該函數的不適用於對單個字符進行計算,因為單個字符四捨五入後都是1
  52. *
  53. * @param c
  54. * @return
  55. */
  56. privatelong calculateLength(CharSequence c) {
  57. double len = 0;
  58. for (int i = 0; i < c.length(); i++) {
  59. int tmp = (int) c.charAt(i);
  60. if (tmp > 0 && tmp < 127) {
  61. len += 0.5;
  62. } else {
  63. len++;
  64. }
  65. }
  66. return Math.round(len);
  67. }
  68. /**
  69. * 刷新剩余輸入字數,最大值新浪微博是140個字,人人網是200個字
  70. */
  71. privatevoid setLeftCount() {
  72. mTextView.setText(String.valueOf((MAX_COUNT - getInputCount())));
  73. }
  74. /**
  75. * 獲取用戶輸入的分享內容字數
  76. *
  77. * @return
  78. */
  79. privatelong getInputCount() {
  80. return calculateLength(mEditText.getText().toString());
  81. }
  82. }
Copyright © Linux教程網 All Rights Reserved