Android EditText追加空格、限制字符等方法示例
前言
使用輸入框時(shí)產(chǎn)品常常會(huì)有一些需求,比如123456789變成123-456-789或者限制一些字符的輸入等等。很多時(shí)候都是網(wǎng)上搜索就完事了,但是每次都去搜索有點(diǎn)浪費(fèi)時(shí)間,而且有些也不符合需求。所以自己寫一篇,以后就可以吃老本了。😝
追加字符
import android.content.Context; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.AttributeSet; import com.ifreegroup.ebbly.lib_common.utils.AppLogUtil; /** * @Describe:自動(dòng)添加占位符的輸入框 * @Date: 2019/06/11 * @Author: dengkewu * @Contact: */ public class PlaceHolderEditText extends android.support.v7.widget.AppCompatEditText { //上次輸入框中的內(nèi)容 private String lastString; //光標(biāo)的位置 private int selectPosition; //輸入框內(nèi)容改變監(jiān)聽 private TextChangeListener listener; //追加字符 private String item = "-"; public PlaceHolderEditText(Context context) { super(context); initView(); } public PlaceHolderEditText(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public PlaceHolderEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } private void initView() { addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } /** * 當(dāng)輸入框內(nèi)容改變時(shí)的回調(diào) * @param s 改變后的字符串 * @param start 改變之后的光標(biāo)下標(biāo) * @param before 刪除了多少個(gè)字符 * @param count 添加了多少個(gè)字符 */ @Override public void onTextChanged(CharSequence s, int start, int before, int count) { //因?yàn)橹匦屡判蛑髎etText的存在 //會(huì)導(dǎo)致輸入框的內(nèi)容從0開始輸入,這里是為了避免這種情況產(chǎn)生一系列問(wèn)題 if (start == 0 && count > 1 && getSelectionStart() == 0) { return; } String textTrim = getText().toString().trim(); if (TextUtils.isEmpty(textTrim)) { return; } //如果 before >0 && count == 0,代表此次操作是刪除操作 if (before > 0 && count == 0) { selectPosition = start; if (TextUtils.isEmpty(lastString)) { return; } //將上次的字符串去空格 和 改變之后的字符串去空格 進(jìn)行比較 //如果一致,代表本次操作刪除的是空格 if (textTrim.equals(lastString.replaceAll(item, ""))) { //幫助用戶刪除該刪除的字符,而不是空格 StringBuilder stringBuilder = new StringBuilder(lastString); stringBuilder.deleteCharAt(start - 1); selectPosition = start - 1; setText(stringBuilder.toString()); } } else { //此處代表是添加操作 //當(dāng)光標(biāo)位于空格之前,添加字符時(shí),需要讓光標(biāo)跳過(guò)空格,再按照之前的邏輯計(jì)算光標(biāo)位置 if ((start + count) % 5 == 0) { selectPosition = start + count + 1; } else { selectPosition = start + count; } } } @Override public void afterTextChanged(Editable s) { //獲取輸入框中的內(nèi)容,不可以去空格 String etContent = getText().toString(); if (TextUtils.isEmpty(etContent)) { if (listener != null) { listener.textChange(""); } return; } //重新拼接字符串 String newContent = addSpaceByCredit(etContent); //保存本次字符串?dāng)?shù)據(jù) lastString = newContent; //如果有改變,則重新填充 //防止EditText無(wú)限setText()產(chǎn)生死循環(huán) if (!newContent.equals(etContent)) { setText(newContent); try { //保證光標(biāo)的位置 setSelection(selectPosition > newContent.length() ? newContent.length() : selectPosition); } catch (Exception e) { //剛好為限制字符的整數(shù)倍時(shí)添加空格后會(huì)出現(xiàn)越界的情況 //AppLogUtil.e("超過(guò)限制字符"); } } //觸發(fā)回調(diào)內(nèi)容 if (listener != null) { listener.textChange(newContent); } } }); } /** * 輸入框內(nèi)容回調(diào),當(dāng)輸入框內(nèi)容改變時(shí)會(huì)觸發(fā) */ public interface TextChangeListener { void textChange(String text); } public void setTextChangeListener(TextChangeListener listener) { this.listener = listener; } /** * 每4位添加一個(gè)空格 * * @param content * @return */ public String addSpaceByCredit(String content) { if (TextUtils.isEmpty(content)) { return ""; } content = content.replaceAll(item, ""); if (TextUtils.isEmpty(content)) { return ""; } StringBuilder newString = new StringBuilder(); for (int i = 1; i <= content.length(); i++) { if (i % 4 == 0 && i != content.length()) { newString.append(content.charAt(i - 1) + item); } else { newString.append(content.charAt(i - 1)); } } return newString.toString(); } /** * 獲取追加字符前輸入內(nèi)容 * @return */ public String getInputText() { return getText().toString().replaceAll(item, ""); } }
核心思路是在文本改變時(shí)獲取到原字符串取出每一個(gè)字符添加上要追加的字符后返回字符串并重新setText。當(dāng)然中間會(huì)有一些坑,比如光標(biāo)位置、刪除時(shí)空格要跳過(guò)以及刪除后會(huì)再追加空格會(huì)造成死循環(huán)的問(wèn)題。當(dāng)然這里很多情況已經(jīng)處理過(guò)了,如果有其他需求比如手機(jī)號(hào)碼的111 1111 1111的形式可以修改addSpaceByCredit這個(gè)方法。
限制字符
借鑒博客Android EditText限制輸入字符的5種實(shí)現(xiàn)方式
et_traveler_content.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) { String editable = et_traveler_content.getText().toString(); String str = stringFilter(editable.toString()); if (!editable.equals(str)) { et_traveler_content.setText(str); //設(shè)置新的光標(biāo)所在位置 et_traveler_content.setSelection(et_traveler_content.getText().toString().length()); } } @Override public void afterTextChanged(Editable s) { } }); public String stringFilter(String str) { // 只允許字母、數(shù)字、英文空白字符 String regEx = "[^a-zA-Z0-9\\s]"; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(str); return m.replaceAll(""); }
這里也是輸入時(shí)做過(guò)濾然后重新setText。只要需要對(duì)正則表達(dá)式熟悉想做什么限制都可以。
MD效果
系統(tǒng)自帶
<android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginStart="15dp" android:padding="0dp" android:layout_centerVertical="true" android:gravity="center_vertical"> <EditText …… /> </android.support.design.widget.TextInputLayout>
只需要用TextInputLayout包裹一層便可以實(shí)現(xiàn)MD效果。
常用屬性
1.明文、密文
if (isShowPwd) { // 可視密碼輸入 setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo .TYPE_TEXT_VARIATION_VISIBLE_PASSWORD); } else { // 非可視密碼狀態(tài) setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD); }
2.默認(rèn)不獲取焦點(diǎn)
父容器設(shè)置(其實(shí)只要布局內(nèi)有一個(gè)控件設(shè)置就可以)
android:focusableInTouchMode="true"
一些第三方庫(kù)
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
- Android 登錄頁(yè)面的實(shí)現(xiàn)代碼(密碼顯示隱藏、EditText 圖標(biāo)切換、限制輸入長(zhǎng)度)
- Android EditText隨輸入法一起移動(dòng)并懸浮在輸入法之上的示例代碼
- Android EditText每4位自動(dòng)添加空格效果
- Android EditText長(zhǎng)按菜單中分享功能的隱藏方法
- Android中多個(gè)EditText輸入效果的解決方式
- Android實(shí)現(xiàn)微信朋友圈評(píng)論EditText效果
- Android EditText監(jiān)聽回車鍵并處理兩次回調(diào)問(wèn)題
- Android實(shí)現(xiàn)EditText添加下劃線
- Android自定義密碼輸入EditTextLayout
- Android EditText限制輸入整數(shù)和小數(shù)的位數(shù)的方法示例
- Android使用EditText小技巧匯總
相關(guān)文章
Android AsyncTask實(shí)現(xiàn)機(jī)制詳細(xì)介紹及實(shí)例代碼
這篇文章主要介紹了Android AsyncTask實(shí)現(xiàn)機(jī)制詳細(xì)介紹及實(shí)例代碼的相關(guān)資料,這里附有示例代碼,幫助大家學(xué)習(xí)理解,需要的朋友可以參考下2016-12-12淺析KJFrameForAndroid框架如何高效加載Bitmap
Bitmap是Android系統(tǒng)中的圖像處理的最重要類之一。用它可以獲取圖像文件信息,進(jìn)行圖像剪切、旋轉(zhuǎn)、縮放等操作,并可以指定格式保存圖像文件。本文主要是從KJFrameForAndroid框架中分析高效加載Bitmap的方法2014-07-07Android自定義dialog可選擇展示年月日時(shí)間選擇欄
這篇文章主要介紹了Android自定義dialog可選擇展示年月日時(shí)間選擇欄,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下2017-03-03Android自定義控件實(shí)現(xiàn)帶文本與數(shù)字的圓形進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)帶文本與數(shù)字的圓形進(jìn)度條,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12Android AlertDialog對(duì)話框用法示例
這篇文章主要介紹了Android AlertDialog對(duì)話框用法,結(jié)合實(shí)例形式分析了AlertDialog對(duì)話框的功能及常見(jiàn)使用技巧,需要的朋友可以參考下2016-06-06詳解Android SpannableString多行圖文混排的應(yīng)用實(shí)戰(zhàn)
本篇文章主要介紹了Android SpannableString多行圖文混排的應(yīng)用實(shí)戰(zhàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Android編程實(shí)現(xiàn)獲取當(dāng)前系統(tǒng)語(yǔ)言及地區(qū)并更改語(yǔ)言的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)獲取當(dāng)前系統(tǒng)語(yǔ)言及地區(qū)并更改語(yǔ)言的方法,涉及Android針對(duì)系統(tǒng)語(yǔ)言及地區(qū)的獲取與設(shè)置相關(guān)操作技巧,需要的朋友可以參考下2017-10-10淺談Android Studio 3.0 工具新特性的使用 Android Profiler 、Device File
這篇文章主要介紹了淺談Android Studio 3.0 工具新特性的使用 Android Profiler 、Device File Explorer的相關(guān)資料,需要的朋友可以參考下2017-11-11Android開發(fā)之ListView實(shí)現(xiàn)Item局部刷新
對(duì)于ListView數(shù)據(jù)的刷新大家都知道,改變Adapter的數(shù)據(jù)源,然后調(diào)用Adapter的notifyDateSetChanged()方法即可。通過(guò)本篇文章給大家詳細(xì)介紹Android開發(fā)之ListView實(shí)現(xiàn)Item局部刷新,感興趣的朋友一起學(xué)習(xí)吧2015-10-10