安卓onTextChanged參數解釋及實現EditText字數監聽 Editable使用

尊重原做者:此篇文章是借鑑原做者地址 的博文 並進行修改和增長補充說明,我只是補充和修改:
我感受這篇文章通過個人補充 市面多少文本操做變化 你都知道怎麼作了.而且感受是很是詳細關於 android 文本編輯框的文本變化 而且通俗易懂(內含動態圖),javascript

爲了你們方便查看 我這裏複製做者博文內容 而且修正部份內容 後面在補充
我正參加CSDN明日之星比賽 還但願您投我一票html

原做者部分(修改部分)

因爲最近作項目要檢測EditText中輸入的字數長度,從而接觸到了Android中EditText的監聽接口,TextWatcher。
它有三個成員方法,第一個after很簡單,這個方法就是在EditText內容已經改變以後調用,重點看下面兩個方法:java

beforeTextChanged(CharSequence s, int start, int count, int after)

這個方法是在Text改變以前被調用,它的意思就是說在原有的文本s中,從start開始的count個字符將會被一個新的長度爲after的文本替換,注意這裏是將被替換,尚未被替換。android

onTextChanged(CharSequence s, int start, int before, int count)

這個方法是在Text改變過程當中觸發調用的,它的意思就是說在原有的文本s中,從start開始的count個字符替換長度爲before的舊文本,注意這裏沒有將要之類的字眼,也就是說一句執行了替換動做。
可能提及來比較抽象,我舉個簡單的例子,好比說咱們監聽一個EditText,默認開始的時候EditText中沒有文本,當咱們輸入LOVE四個字母的時候,在打印信息中我輸出各個參數看一下參數的變化。sql

10-18 16:40:21.528: D/Debug(4501): beforeTextChanged 被執行----> s=----start=0----after=1----count=0
10-18 16:40:21.528: D/Debug(4501): onTextChanged 被執行---->s=L----start=0----before=0----count=1
10-18 16:40:21.532: D/Debug(4501): afterTextChanged 被執行---->L
10-18 16:40:29.304: D/Debug(4501): beforeTextChanged 被執行----> s=L----start=1----after=1----count=0
10-18 16:40:29.308: D/Debug(4501): onTextChanged 被執行---->s=LO----start=1----before=0----count=1
10-18 16:40:29.308: D/Debug(4501): afterTextChanged 被執行---->LO
10-18 16:40:32.772: D/Debug(4501): beforeTextChanged 被執行----> s=LO----start=2----after=1----count=0
10-18 16:40:32.772: D/Debug(4501): onTextChanged 被執行---->s=LOV----start=2----before=0----count=1
10-18 16:40:32.776: D/Debug(4501): afterTextChanged 被執行---->LOV
10-18 16:40:34.772: D/Debug(4501): beforeTextChanged 被執行----> s=LOV----start=3----after=1----count=0
10-18 16:40:34.772: D/Debug(4501): onTextChanged 被執行---->s=LOVE----start=3----before=0----count=1
10-18 16:40:34.776: D/Debug(4501): afterTextChanged 被執行---->LOVE

經過上面的打印信息咱們能夠發如今輸入L以前beforeTextChanged被執行,s爲空,因此s輸入空,start=0,也就是從位置0開始,count=0,也就是0個字符將會被替換,after=1,也就是說0個字符將會被一個新的長度爲after=1的文本(也就是L)替換。
當輸入發生改變的時候onTextChanged被執行,此時s=L也就是輸入的字母L,從start=0開始,count=1個字符替換了長度爲before=0的舊文本。通俗點將就是字母L從位置0開始替換了原來的空文本,下面的就能夠依次類推了。那麼咱們如何利用這個接口監聽EditText的文本變化來實現限制輸入字數的功能呢,我相信你們都有本身的想法了,這裏我給出本身的一個簡單實現,主要代碼以下:markdown

source_des.addTextChangedListener(new TextWatcher() { 
    private CharSequence temp; 
    private int selectionStart; 
    private int selectionEnd; 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
        Log.d(TAG, "onTextChanged 被執行---->s=" + s + "----start="+ start 
          + "----before="+before + "----count" +count); temp = s; 
    }

    public void beforeTextChanged(CharSequence s, int start, int count,int after) { 
        Log.d(TAG, "beforeTextChanged 被執行----> s=" + s+"----start="+ start 
          + "----after="+after + "----count" +count); 
    } 

    public void afterTextChanged(Editable s) { 
        Log.d(TAG, "afterTextChanged 被執行---->" + s); 
        //獲取光標開始的位置
        selectionStart = source_des.getSelectionStart(); 
        //獲取光標結束的位置
        selectionEnd = source_des.getSelectionEnd(); 
        //這裏其實selectionStart == selectionEnd 
        // 你們能夠把獲取的位置放入beforeTextChanged 而後選擇部分文字(選擇部分位置用光標選擇2個以上) 刪除能夠看到效果 我後面作實驗
        if (temp.length() > MAX_LENGTH) { 
            Toast.makeText(MainActivity.this, "只能輸入九個字", 
              Toast.LENGTH_SHORT).show();
              //刪除部分字符串 爲[x,y) 包含x位置不包含y
              //也就是說刪除 位置x到y-1 
            s.delete(selectionStart - 1, selectionEnd); 
            int tempSelection = selectionEnd; 
            //這裏我修改了原做者 不須要這部
            //source_des.setText(s); 
            //若是你setText 傳入s 的話會將編輯框的光標移到文本框最前面 因此這裏我也註釋了原做者
            //source_des.setSelection(tempSelection); 
        } 
    } 
});

補充部分

好了你們看到了增長文本動態監聽 那麼咱們看看刪除會怎麼觸發事件
實驗代碼:app

editText.addTextChangedListener(new TextWatcher() {
            private CharSequence temp;
            private int selectionStart;
            private int selectionEnd;

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                Log.d(TAG, "onTextChanged 被執行---->s=" + s + "----start="+ start
                        + "----before="+before + "----count" +count); temp = s;
                Log.e(TAG, "onTextChanged--getSelectionStart: " + editText.getSelectionStart());
                Log.e(TAG, "onTextChanged---getSelectionEnd: " + editText.getSelectionEnd());
            }

            public void beforeTextChanged(CharSequence s, int start, int count,int after) {
                Log.d(TAG, "beforeTextChanged 被執行----> s=" + s+"----start="+ start
                        + "----after="+after + "----count" +count);
                Log.e(TAG, "beforeTextChanged---getSelectionStart: " + editText.getSelectionStart());
                Log.e(TAG, "beforeTextChanged---getSelectionEnd: " + editText.getSelectionEnd());
            }

            public void afterTextChanged(Editable s) {
                Log.d(TAG, "afterTextChanged 被執行---->" + s);
                selectionStart = editText.getSelectionStart();
                selectionEnd = editText.getSelectionEnd();
                Log.e(TAG, "afterTextChanged---getSelectionStart: " + editText.getSelectionStart());
                Log.e(TAG, "afterTextChanged---getSelectionEnd: " + editText.getSelectionEnd());

            }
        });

咱們這裏輸入LOVE而後刪除’ov’兩個字母看看會發生
動態圖顯示步驟:
這裏寫圖片描述ide

能夠看到我把光標放入ov外面 那麼光標開始位置爲1 ,結束位置爲3.而後刪除ui

咱們看看日誌this

12-03 12:20:22.355 21082-21082/a.fmy.com.test D/FMY: beforeTextChanged 被執行----> s=love----start=1----after=0----count2
12-03 12:20:22.355 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionStart: 1
12-03 12:20:22.355 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionEnd: 3
12-03 12:20:22.359 21082-21082/a.fmy.com.test D/FMY: onTextChanged 被執行---->s=le----start=1----before=2----count0
12-03 12:20:22.359 21082-21082/a.fmy.com.test E/FMY: onTextChanged--getSelectionStart: 1
12-03 12:20:22.359 21082-21082/a.fmy.com.test E/FMY: onTextChanged---getSelectionEnd: 1
12-03 12:20:22.412 21082-21082/a.fmy.com.test D/FMY: afterTextChanged 被執行---->le
12-03 12:20:22.412 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionStart: 1
12-03 12:20:22.412 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionEnd: 1

這裏我放一張有顏色區分圖片 (和上面同樣的 只不過方便你們查看)
這裏寫圖片描述

咱們先來看看beforeTextChanged的日誌部分

12-03 12:20:22.355 21082-21082/a.fmy.com.test D/FMY: beforeTextChanged 被執行----> s=love----start=1----after=0----count2
12-03 12:20:22.355 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionStart: 1
12-03 12:20:22.355 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionEnd: 3

s:文字沒有改變前字符串
start:準備要變化文本的位置下標 ,咱們這裏選擇’ov’位置 因此這裏相對應’love’位置爲1
count:相對沒改變前舊文本文本減小數量 由於咱們這裏要刪除’ov’因此爲2
after:新文本新加入的字符數量 這裏沒有增長反而減小 因此爲0

getSelectionStart:咱們光標的位置不是o的左邊嗎?因此爲1
getSelectionEnd:光標位置在v右邊 因此爲3 你們回去看下動態圖


咱們最後來看一下另外onTextChanged
這部分的日誌以下:

12-03 12:20:22.359 21082-21082/a.fmy.com.test D/FMY: onTextChanged 被執行---->s=le----start=1----before=2----count0
12-03 12:20:22.359 21082-21082/a.fmy.com.test E/FMY: onTextChanged--getSelectionStart: 1
12-03 12:20:22.359 21082-21082/a.fmy.com.test E/FMY: onTextChanged---getSelectionEnd: 1

s:被改變後的文本 由於咱們這裏刪除刪除’ov’ 因此爲le
start:文本開始改變的位置 ‘ov’相對本來文本的開始位置1,因此這裏返回1
before:改變以前舊文本減小的數量 這裏 ‘love’減小 ‘ov’至關於減小了2
count:新文本添加數量 這裏是減小2因此返回0

getSelectionStart 這裏刪除後的光標狀態 因此等於1
getSelectionEnd 這裏刪除後的光標狀態 因此開始座標等結束座標 所以等於1

補充部分2

咱們假設剪切板內容’12’ (意思是說咱們賦值了12字符串在剪切板,只要一粘貼就會出現’12’)

那麼咱們作一個實驗 在love上 用光標選擇’ov’ 而後粘貼’12’
動態圖(你們耐心等下):
這裏寫圖片描述

這裏日誌爲:

12-03 12:51:25.347 21082-21082/a.fmy.com.test D/FMY: beforeTextChanged 被執行----> s=love----start=1----after=2----count2
12-03 12:51:25.347 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionStart: 3
12-03 12:51:25.347 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionEnd: 3
12-03 12:51:25.348 21082-21082/a.fmy.com.test D/FMY: onTextChanged 被執行---->s=l12e----start=1----before=2----count2
12-03 12:51:25.348 21082-21082/a.fmy.com.test E/FMY: onTextChanged--getSelectionStart: 3
12-03 12:51:25.348 21082-21082/a.fmy.com.test E/FMY: onTextChanged---getSelectionEnd: 3
12-03 12:51:25.378 21082-21082/a.fmy.com.test D/FMY: afterTextChanged 被執行---->l12e
12-03 12:51:25.378 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionStart: 3
12-03 12:51:25.379 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionEnd: 3

這裏我就簡單說下光標位置的問題:由於替換相同長度的文本 因此光標並無移動 位於選擇的字符串+1的 位置 ,咱們這裏選擇’ov’ 因此開始和結束爲:3 (o的位置)

beforeTextChanged 日誌解釋:

12-03 12:51:25.347 21082-21082/a.fmy.com.test D/FMY: beforeTextChanged 被執行----> s=love----start=1----after=2----count2
12-03 12:51:25.347 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionStart: 3
12-03 12:51:25.347 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionEnd: 3

start:文本開始位置,由於咱們從’ov’的’o’開始改變因此爲1(love中o不是相對是1嘛)
after:新文本增長的數量 由於增長了12因此兩個字符就是2
count:本來舊字符串減小的數量 減小’ov’因此是2
其餘的同窗們能夠本身推斷

補充部分3

這裏咱們再看看替換不一樣長度的文本

咱們這裏 光標選擇’ov’ 替換爲’12345’(剪切板以保存)

這裏寫圖片描述

12-03 13:01:25.735 21082-21082/a.fmy.com.test D/FMY: beforeTextChanged 被執行----> s=love----start=1----after=5----count2
12-03 13:01:25.735 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionStart: 3
12-03 13:01:25.735 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionEnd: 3
12-03 13:01:25.737 21082-21082/a.fmy.com.test D/FMY: onTextChanged 被執行---->s=l12345e----start=1----before=2----count5
12-03 13:01:25.737 21082-21082/a.fmy.com.test E/FMY: onTextChanged--getSelectionStart: 6
12-03 13:01:25.737 21082-21082/a.fmy.com.test E/FMY: onTextChanged---getSelectionEnd: 6
12-03 13:01:25.770 21082-21082/a.fmy.com.test D/FMY: afterTextChanged 被執行---->l12345e
12-03 13:01:25.770 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionStart: 6
12-03 13:01:25.770 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionEnd: 6

能夠 替換字符串的時候光標 開始等於結束的

補充部分4 Editable

咱們想直接操做文本編輯框的文本的時候 想快速插入和添加 能夠考慮這個方法

咱們看看兩個例子 獲取 文本編輯框中的字符串而且添加 ‘你好’在後面;
不使用Editable

String s = editText.getText().toString();
        s +="你好";
        editText.setText(s);

來咱們看看使用Editable

editText.getText().append("你好");
  1. 咱們看看怎麼獲取Editable
    很是簡單隻須要用文本編輯框調用getText()方法

     Editable text = editText.getText();
  2. 相關API
    在文本編輯框後面添加字符串

    Editable editable = editText.getText();
            editable.append("你好");

    刪除文本編輯框部份內容,假設你此時文本編輯框的內容’love’你想刪除中間的ov

    Editable editable = editText.getText();
            //start爲要刪除文本的開始下標 end爲結束下標(不包括) //也就是說 [start,end) //editable.delete(start,end);
            //注意end必須等於start 否則奔潰 // 也就是 end>=start //咱們看看刪除love 中的ov editable.delete(1,3);

    在文本編輯框中字符串的某個部分插入字符,假設咱們的文本編輯框內容爲’love’那麼咱們想插入 ‘a’到’o’後面也就是’loave’

Editable editable = editText.getText();
        String a = "a";
        //love 插入o後面 o位置相對於字符的1
        //第一個參數 插入 的位置 
        // 第二個參數 要插入字符串
        // 第三個參數 插入的字符串的開始位置
        // 第四個參數 插入的字符串的結束位置(不包含)
        editable.insert(1,"a",0,a.length());
       // 下面方法和上面的等價
        //editable.insert(1,"a");
刪除文本編輯框全部內容
Editable editable = editText.getText();
        editable.clear();

替換文本編輯框部份內容
假設咱們將文本框 ‘love’中」o」替換爲」a」 也就是說’lave’

Editable editable = editText.getText();
        //第一個參數 替換位置
        //第二個 替換結束爲止(不包含)
        //第三個 替換的字符串
        editable.replace(1,2,"a");

        String a = "a";
        //第一個參數 替換位置
        //第二個 替換結束爲止(不包含)
        //第三個 替換的字符串
        //第四個 替換文本的開始位置
        //第五個 替換文本結束位置 不包含
        editable.replace(1,2,"a",0,a.length());
相關文章
相關標籤/搜索