多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > Android限制EditText只能輸入中文或者指定內容的實現

Android限制EditText只能輸入中文或者指定內容的實現

來源:程序員人生   發布時間:2017-03-13 17:30:21 閱讀次數:6063次

最近項目中要限制EditText中只能輸入中文,之前寫過1個限制EditText只能輸入中文的實現,不過存在1些問題,而且擴大性不是很好,所以換了1種方法來實現.
先看1下效果圖:

這里寫圖片描述


具體實現

1般對EditText的操作及處理都是用addTextChangedListener方法來對EditText進行監聽,以后在監聽方法中去做處理.這里也打算用這個種方法來做,大體的思路是監聽EditText中輸入的內容,然后將不是中文的部份清除掉,也就是置為空.所以大概應當這樣寫

 mLimitEt.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) {
            // 1.處理輸入的內容s:清除其中不是中文的部份
            ...
            // 2.設置處理完的s
            mLimitEt.setText("處理以后的s");
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

處理的方法這里先不寫,先來看1下這樣寫會出現的1個問題,運行1下,輸入1些內容會發現程序崩潰了,查看崩潰信息,會發現出現了StackOverflowError異常,這是甚么緣由呢?帶著疑問去扒了1下源碼(看源碼時遇到1個問題,升級完Studio以后,發現沒法查看源碼了,查了1些資料解決了,也有相同問題的童鞋可以參考下我寫的 Mac版Android Studio查看不到源碼的解決方法,windows版解決方法也類似)出現異常的位置在 mLimitEt.setText()這句代碼上,所以先看1下setText()方法.setText方法在TextView中,看1下實現(這里只關心引發異常的部份,其他部份的內容不討論)

private void setText(CharSequence text, BufferType type,
                         boolean notifyBefore, int oldlen) {
   ...
   // Text改變前的回調解理
   sendBeforeTextChanged(mText, 0, oldlen, text.length());
   ...
   // Text改變中的回調解理
   sendOnTextChanged(text, 0, oldlen, textLength);
   ...
   // Text改變后的回調解理
   sendAfterTextChanged((Editable) text); 

}

在setText方法中可以看到這幾個方法,然后看1下這些方法做的處理是甚么

     /**
     * Not private so it can be called from an inner class without going
     * through a thunk.
     */
       void sendOnTextChanged(CharSequence text, int start, int before, int after) {
        if (mListeners != null) {
            final ArrayList<TextWatcher> list = mListeners;
            final int count = list.size();
            for (int i = 0; i < count; i++) {
                list.get(i).onTextChanged(text, start, before, after);
            }
        }

        if (mEditor != null) mEditor.sendOnTextChanged(start, after);
    }

     /**
     * Not private so it can be called from an inner class without going
     * through a thunk.
     */
    void sendAfterTextChanged(Editable text) {
        if (mListeners != null) {
            final ArrayList<TextWatcher> list = mListeners;
            final int count = list.size();
            for (int i = 0; i < count; i++) {
                list.get(i).afterTextChanged(text);
            }
        }
        hideErrorIfUnchanged();
    }

看1下這些方法,能不能發現點甚么,可以看到有1個ArrayList< TextWatcher >對象,先進行判空處理,如果這個對象中存在TextWatcher監聽,則逐條進行回調操作.再回頭看1下之前寫的EditText中回調方法的實現,在回調中,對這個EditText進行了setText操作,由于EditText實現了TextWatcher的回調接口,這樣就致使了無窮循環 setText->onTextChanged->setText…… 終究致使程序崩潰.那該如何解決這個問題呢.其實很簡單,看1下代碼

 mLimitEt.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) {
            // 1.處理輸入的內容s:清除其中不是中文的部份
            ...
            // 2.刪除監聽
            mLimitEt.removeTextChangedListener(this);
            // 3.設置處理完的s
            mLimitEt.setText("處理以后的s");
            // 4.重新添加監聽
            mLimitEt.addTextChangedListener(this);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

在setText之前先刪除之前的回調監聽,setText時由于沒有TextWatcher的監聽方法,所以不會出現無窮循環的情況,當setText以后再重新添加回調監聽,這樣就避免了崩潰的產生.以后看1下清除非中文部份的實現,直接看代碼

    /**
     * 清除不是中文的內容
     *
     * @param regex
     * @return
     */
    private String clearLimitStr(String regex, String str) {
        return str.replaceAll("[^\u4E00-\u9FA5]", "");
    }

用了String的replaceAll方法來處理輸入的內容(用了正則表達式,使用起來很簡單).在onTextChanged和afterTextChanged方法中,得到的輸入內容實際上是整體的輸入內容,所以用replaceAll方法,可以去打印1下這幾個方法中的參數,這里就不做了.看1下整體代碼

LimitInputTextWatcher:

package com.example.junweiliu.limitinputdemo;

import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;

/**
 * Created by junweiliu on 17/1/6.
 */
public class LimitInputTextWatcher implements TextWatcher {
    /**
     * et
     */
    private EditText et = null;
    /**
     * 挑選條件
     */
    private String regex;
    /**
     * 默許的挑選條件(正則:只能輸入中文)
     */
    private String DEFAULT_REGEX = "[^\u4E00-\u9FA5]";

    /**
     * 構造方法
     *
     * @param et
     */
    public LimitInputTextWatcher(EditText et) {
        this.et = et;
        this.regex = DEFAULT_REGEX;
    }

    /**
     * 構造方法
     *
     * @param et    et
     * @param regex 挑選條件
     */
    public LimitInputTextWatcher(EditText et, String regex) {
        this.et = et;
        this.regex = regex;
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        String str = editable.toString();
        String inputStr = clearLimitStr(regex, str);
        et.removeTextChangedListener(this);
        // et.setText方法可能會引發鍵盤變化,所以用editable.replace來顯示內容
        editable.replace(0, editable.length(), inputStr.trim());
        et.addTextChangedListener(this);

    }

    /**
     * 清除不符合條件的內容
     *
     * @param regex
     * @return
     */
    private String clearLimitStr(String regex, String str) {
        return str.replaceAll(regex, "");
    }
}

為了擴大性,提出來了1個類,提供了兩個構造方法,如果需要限制其他的特殊內容,可以設置正則的規則.固然如果很簡單的話,用EidtText自帶的digits屬性就能夠了.還有1個問題,需要注意,代碼中沒有用et.setText方法,是由于setText方法可能引發鍵盤變化異常,所以這里用 editable.replace(0, editable.length(), inputStr.trim());這個方法和setText方法的實現效果是1樣的.不過也需要對監聽進行處理,緣由也是由于會引發無窮循環,感興趣的童鞋可以去看1下.

完全代碼

MainActivity:

package com.example.junweiliu.limitinputdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {
    /**
     * et
     */
    private EditText mLimitEt;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mLimitEt = (EditText) findViewById(R.id.et_limit);
        mLimitEt.addTextChangedListener(new LimitInputTextWatcher(mLimitEt));
        // 去除除a-z  A-Z與0⑼和中文的其他符號
//        mLimitEt.addTextChangedListener(new LimitInputTextWatcher(mLimitEt, "[^a-zA-Z0⑼\u4E00-\u9FA5]"));
    }
}

activity_main:

<?xml version="1.0" encoding="utf⑻"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.example.junweiliu.limitinputdemo.MainActivity">
    <!--輸入框-->
    <!--android:digits="1234567890"-->
    <EditText
            android:id="@+id/et_limit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:hint="我是1個受限制的輸入框"/>
    <!--輸入框-->
    <EditText
            android:layout_below="@+id/et_limit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:text="復制我fuzhiwo845"
            android:hint=""/>
</RelativeLayout>
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 亚洲乱码中文字幕综合 | 欧美高清性 | 亚洲免费闲人蜜桃 | 久久久久avav久久久 | 欧美一级人与动毛片免费播放 | 波多野结衣视频在线播放 | 欧美激情videossex护士 | 久久精品国产第一区二区 | 久久久久久一级毛片免费野外 | 精彩视频在线观看 | 久久久久久久国产精品视频 | 国产视频一二区 | 日韩国产欧美精品综合二区 | 色偷偷青青草原在线视频 | 欧美一级淫片免费观看 | jlzzjlzzjlzz亚洲女| 亚洲人在线播放 | 欧美亚洲综合另类在线观看 | 亚洲a视频在线 | 琪琪午夜伦埋大全影院 | 亚洲国产精品日韩一线满 | 欧美一级二级毛片视频 | 999毛片免费 | 校园春色另类 | 二区国产 | 高清一级毛片免免费看 | 在线第一页 | 真实男女xx00动态视频 | 亚洲一区二区福利视频 | 欧美性bbbbbxxxxxddd | 日韩中文欧美 | 狂野欧美性猛交xxxx免费按摩 | 精品区| jjzz黄色| 亚洲精品欧美精品中文字幕 | 欧美俄罗斯一级毛片 | 久久天天躁狠狠躁夜夜 | 韩国三级hd中文字幕一男多女 | 中文字幕在线播 | 波多野结衣视频免费 | 日本三级午夜理伦三级三 |