Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android EditText輸入字數限制總結(包括中文輸入內存溢出的解決方法)

Android EditText輸入字數限制總結(包括中文輸入內存溢出的解決方法)

編輯:關於Android編程


限定EditText輸入個數的解決方案很多,但是一般主要考慮兩點,也就是處理兩件事:
(1)不同語言字符(英文、中文等)處理方式
(2)輸入字符達到數目後,是否仍然允許用戶輸入

第一點,涉及的東東其實蠻多,不同語言在不同編碼中占據字節數等,不同語言在U8等編碼的表示范圍等,這一整塊知識很豐富,

自己暫時沒有理的特別順,稍後整理再說吧。

第二點,目前主流app的處理方案也各有不同,qq5.0以前的版本,發表說說貌似是沒有字數限制的(我試了一個350字左右的照樣發),

5.0以後限制了,這樣如果用戶輸入字數超過限制便顯示負數,但是仍然允許用戶輸入,就是不能發表了。這樣就把處理權全部交給用戶了,

其實更省事了!

實現吧。

方法一:
布局中限制。
android:maxLength=10  // 即限制最大輸入字符個數為10。
(1)中英文都算一個字符。
(2)字數到,不能輸入

方法二:
InputFilter限制,同布局中限制類似。
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(10)});
(1)中英文都算一個字符。
(2)字數到,不能輸入

方法三:
TextWatcher限制。這裡如果字數達到限制仍然允許用戶輸入的情況不多說,好實現。

crash問題:使用搜狗輸入法時,在字數將要或者已經達到限制之後,一次輸入大量中文(不按空格,一直打字,知道搜狗的緩存字符達到上限),

crash,stackoverflow 內存溢出。呵呵,百度輸入法不會哈。

解決:監聽器中動態去除、添加就ok了。見下邊方案一

方案一,中文按兩個,英文按一個。個數到限制,用戶不能輸入
private TextWatcher textWatcher = new TextWatcher() {
    private int editStart;
    private int editEnd;
    private int maxLen = 10; // the max byte
	@Override
	public void beforeTextChanged(CharSequence s, int start, int count, int after) {
		Log.d(TextChanged, ---->beforeTextChanged : start =  + start +  count =  + count +  after =  + after);
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
	}

	@Override
	public void afterTextChanged(Editable s) {
		editStart = opinion.getSelectionStart();
		editEnd = opinion.getSelectionEnd();
		// 先去掉監聽器,否則會出現棧溢出
		opinion.removeTextChangedListener(textWatcher);
		if (!TextUtils.isEmpty(opinion.getText())) {
			String etstring = opinion.getText().toString().trim();
			while (calculateLength(s.toString()) > maxLen) {
				s.delete(editStart - 1, editEnd);
				editStart--;
				editEnd--;
				Log.d(TextChanged, editStart =  + editStart +  editEnd =  + editEnd);
			}
		}

		opinion.setText(s);
		opinion.setSelection(editStart);

		// 恢復監聽器
		opinion.addTextChangedListener(textWatcher);
		// end by zyf --------------------------
	}
	private int calculateLength(String etstring) {
		char[] ch = etstring.toCharArray();

		int varlength = 0;
		for (int i = 0; i < ch.length; i++) {
			// changed by zyf 0825 , bug 6918,加入中文標點范圍 , TODO 標點范圍有待具體化
			if ((ch[i] >= 0x2E80 && ch[i] <= 0xFE4F) || (ch[i] >= 0xA13F && ch[i] <= 0xAA40) || ch[i] >= 0x80) { // 中文字符范圍0x4e00 0x9fbb
				varlength = varlength + 2;
			} else {
				varlength++;
			}
		}
		Log.d(TextChanged, varlength =  + varlength);
		// 這裡也可以使用getBytes,更准確嘛
        // varlength = etstring.getBytes(CharSet.forName(GBK)).lenght;// 編碼根據自己的需求,注意u8中文占3個字節...
		return varlength;
	}
};


方案二
// 達到限制字數後,如果在文字中間輸入文字或者空格,最後的字符會被刪除
titleTv.addTextChangedListener(new TextWatcher() {

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count, int after) {

	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {

	}

	@Override
	public void afterTextChanged(Editable s) {
		 // add by zyf 0825 . 多余的從新輸入的位置刪除,而不是最後
		   editStart = opinion.getSelectionStart();
		   editEnd = opinion.getSelectionEnd();

		if (!TextUtils.isEmpty(titleTv.getText())) {
			int varlength = 0;
			int size = 0;
			String etstring = titleTv.getText().toString().trim();
			char[] ch = etstring.toCharArray();
			for (int i = 0; i < ch.length; i++) {
				size++;
				if (ch[i] >= 0x4e00 && ch[i] <= 0x9fbb) {
					varlength = varlength + 2;
				} else
					varlength++;
				if (varlength > 80) {
					break;
				}
			}
			if (varlength > 80) {
				 s.delete(size - 1, etstring.length());
				 // add by zyf 0825 . 多余的從新輸入的位置刪除,而不是最後
				 // s.delete(editStart - 1, editEnd); // crash stackoverflow,解決方法參考上邊方案一
			}
		}
	}

}); 
 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved