Android EditText每4位自動添加空格效果
基本功能
剛拿到需求,很簡單的一個功能,二話不說,很快就出來了:
完美!順利上線!
沒過幾天領導拿著手機過來說:“這一堆數字在一起看著很費勁,像其他App一樣,加個空格吧!”
于是就有了這個demo。
拓展功能
下面就來在基本功能上做拓展:每4位,自動添加空格。
看似很小的功能,在開發(fā)的過程中,遇到了非常多的問題與難點:
- EditText輸入框監(jiān)聽死循環(huán)
- 輸入框中的空格無法刪除(刪除又添加)
- 從中間刪除一個數字產生的一系列問題
- 輸入框光標位置的控制問題
之前踩坑的過程就不再贅述了,太心酸....
經過一系列的實驗,最后定下來的思路如下:
- 當輸入框的內容改變時,就將內容取出拆分為一個一個的字符,在每4位的中間添加空格,最后一個4位不能添加。用這種拼接字符的方法是為了解決當用戶刪除中間的數字,會導致空格位置錯位的問題。
- 當用戶刪除中間的字符時,要記錄該動作并且記錄光標位置,保證重新排序完成后,光標的位置在應該在的位置。
大概就這2步,就可以實現這個功能,下面一步一來,我們先實現空格的添加,保證內容永遠滿足4位后一個空格:
下面先看EditText的監(jiān)聽:
et_credit_number.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) { //獲取輸入框中的內容,不可以去空格 String etContent = EditTextUtils.getText(et_credit_number); if (TextUtils.isEmpty(etContent)) { bt_submit.setEnabled(false); return; } //重新拼接字符串 String newContent = AppUtils.addSpeaceByCredit(etContent); //如果有改變,則重新填充 //防止EditText無限setText()產生死循環(huán) if (!etContent.equals(newContent)) { et_credit_number.setText(newContent); //保證光標在最后,因為每次setText都會導致光標重置 //這樣最基本地解決了光標亂跳的問題 et_credit_number.setSelection(newContent.length()); } //判斷是否滿足信用卡格式,注意去空格判斷 if (MatcheUtils.isCreditNumber(newContent.replaceAll(" ", ""))) { bt_submit.setEnabled(true); return; } bt_submit.setEnabled(false); } });
沒有難點,重新拼接字符串我單獨封裝了出來:
public static String addSpeaceByCredit(String content) { if (TextUtils.isEmpty(content)) { return ""; } //去空格 content = content.replaceAll(" ", ""); if (TextUtils.isEmpty(content)) { return ""; } //卡號限制為16位 if (content.length() > 16) { content = content.substring(0, 16); } StringBuilder newString = new StringBuilder(); for (int i = 1; i <= content.length(); i++) { //當為第4位時,并且不是最后一個第4位時 //拼接字符的同時,拼接一個空格 //如果在最后一個第四位也拼接,會產生空格無法刪除的問題 //因為一刪除,馬上觸發(fā)輸入框改變監(jiān)聽,又重新生成了空格 if (i % 4 == 0 && i != content.length()) { newString.append(content.charAt(i - 1) + " "); } else { //如果不是4位的倍數,則直接拼接字符即可 newString.append(content.charAt(i - 1)); } } return newString.toString(); }
這里每一步的含義,我都寫了注釋,應該問題不大,下面運行一下:
完美!空格正常添加了!
但是光標亂跳的問題,我特地演示了一下。
用字符排序的方式來做這個功能的原因是這個,當用戶從中間刪除字符時,我們需要將所有添加的空格位置都進行審查,并重新進行空格的添加,所以我認為重新排序字符是非常恰當的一種做法。當然這僅僅是我的愚見,可能有更優(yōu)的做法。
現在我們就要進行第二步,當用戶刪除中間字符時,我們要判斷用戶本次操作是刪除字符,并且保存本次刪除的光標位置,在刪除完成、排序完成之后,將光標移動到保存的光標位置。
思路有了,下面就看最終代碼好了。
功能展示
輸入框監(jiān)聽的代碼:
et_credit_number.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) { //因為重新排序之后setText的存在 //會導致輸入框的內容從0開始輸入,這里是為了避免這種情況產生一系列問題 if (start == 0 && count > 0) { return; } String editTextContent = EditTextUtils.getText(et_credit_number); if (TextUtils.isEmpty(editTextContent) || TextUtils.isEmpty(lastString)) { return; } editTextContent = AppUtils.addSpeaceByCredit(editTextContent); //如果最新的長度 < 上次的長度,代表進行了刪除 if (editTextContent.length() <= lastString.length()) { deleteSelect = start; } else { deleteSelect = editTextContent.length(); } } @Override public void afterTextChanged(Editable s) { //獲取輸入框中的內容,不可以去空格 String etContent = EditTextUtils.getText(et_credit_number); if (TextUtils.isEmpty(etContent)) { bt_submit.setEnabled(false); return; } //重新拼接字符串 String newContent = AppUtils.addSpeaceByCredit(etContent); //保存本次字符串數據 lastString = newContent; //如果有改變,則重新填充 //防止EditText無限setText()產生死循環(huán) if (!etContent.equals(newContent)) { et_credit_number.setText(newContent); //保證光標的位置 et_credit_number.setSelection(deleteSelect > newContent.length() ? newContent.length() : deleteSelect); } //判斷是否滿足信用卡格式,注意去空格判斷 if (MatcheUtils.isCreditNumber(newContent.replaceAll(" ", ""))) { bt_submit.setEnabled(true); return; } bt_submit.setEnabled(false); } });
這邊主要利用了onTextChanged()的監(jiān)聽,判斷用戶操作是刪除操作時,保存光標的位置。
小結
項目我已經上傳到了我的GitHub,有興趣的同學可以去參考一下。
這個功能的坑遠遠超出了我的想象,我才不會說這個項目我就運行了100遍而已!
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。
相關文章
Android用tabhost實現 界面切換,每個界面為一個獨立的activity操作
這篇文章主要介紹了Android用tabhost實現 界面切換,每個界面為一個獨立的activity操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-099個非常棒的Android代碼編輯器 移動開發(fā)者的最愛
這篇文章主要為大家分享了9個非常棒的Android代碼編輯器,據說這可是移動開發(fā)者的最愛,知道是哪九個Android代碼編輯器2015-12-12Android中使用include標簽和merge標簽重復使用布局
這篇文章主要介紹了Android中使用include標簽和merge標簽重復使用布局,文中講解了創(chuàng)建可復用布局的例子以及include標簽和merge標簽使用例子,需要的朋友可以參考下2014-06-06