Android EditText TextWatcher 回调方法参数说明

有些时候需要用到TextWatcher来监听EditText的内容变化,

而TextWatcher有三个回调方法,

这三个回调方法在Android的API Document中说的并不是很容易理解,

我尝试用我的思路以及试验解释一下这三个回调方法的参数。


// **************************************************************

// 这一部分比较枯燥可以跳过,直接读试验部分

// 试验部分的结果会对比这一部分的Javadoc来确认对试验结果理解的正确性


三个回调方法分别是 (按回调的先后顺序):

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

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

public void afterTextChanged(Editable s) {}


beforeTextChanged -- Javadoc:

This method is called to notify you that, within s, the count characters beginning at start are about to be replaced by new text with lengthafter. It is an error to attempt to make changes tos from this callback.



onTextChanged -- Javadoc:

This method is called to notify you that, within s, the count characters beginning at start have just replaced old text that had lengthbefore. It is an error to attempt to make changes tos from this callback.


afterTextChanged -- Javadoc:

This method is called to notify you that, somewhere withins, the text has been changed. It is legitimate to make further changes tos from this callback, but be careful not to get yourself into an infinite loop, because any changes you make will cause this method to be called again recursively. (You are not told where the change took place because other afterTextChanged() methods may already have made other changes and invalidated the offsets. But if you need to know here, you can useSpannable.setSpan inonTextChanged to mark your place and then look up from here where the span ended up.

// **************************************************************


// **************************************************************

// 试验部分开始

// 试验1:

// Part 1: 粘贴 “cmd” 到EditText

// Part 2: 选中“cm”并删除

Android EditText TextWatcher 回调方法参数说明_第1张图片

首先看 Part 1:


cmd

s start count after / before
beforeTextChanged  s =  0 0 a = 3
onTextChanged  s = cmd 0 3 b = 0
afterTextChanged  s = cmd



结合上面的Javadoc 来看:

beforeTextChanged:the count characters beginning atstart are about to be replaced by new text with length after. It is an error to attempt to make changes to s from this callback.

也就是说:从start(=0) 位置开始,有count(=0)个字符将被替换为长度为after(=3)的新文字。

解释:

  1. 因为我们是从最开始来粘贴(可以理解成输入,但输入不能一下输入多个字符)cmd,所以 start = 0; 
  2. 因为我们的操作是纯粘贴(并没有选中其他的字符然后粘贴 -- 这个是替换),并没有文字被替换掉,也就是说我们的操作并没有删除原有的任何文字,所以count = 0.
  3. 因为我们将要粘贴的文字是 cmd,他共有3个字符,所以after= 3;
  4. 因为这个回调方法是在粘贴之前回调,所以此时edittext中的内容并未发生变化,所以 s = 空串。


onTextChanged -- Javadoc:

This method is called to notify you that, within s, the count characters beginning atstart have just replaced old text that had length before. It is an error to attempt to make changes to s from this callback.

也就是说:从start(=0) 位置开始,有count(=3)个字符刚刚替换了长度为before(=0)的旧文字。

解释:

  1. 因为我们是从最开始来粘贴(可以理解成输入,但输入不能一下输入多个字符)cmd,所以 start = 0; 
  2. 因为我们要粘贴的内容是 cmd, 他共有3个字符,所以 count = 3
  3. 因为我们是纯粘贴,并没有删除其他的文字,所以 before = 0
  4. 因为这个回调方法是发生在文字发生改变的时候,所以s = cmd
afterTextChanged(Editable s)  只有一个参数,那就是操作完成之后 EditText 中的最终内容,所以他就是 s = cmd (此处无需更多解释)。

从上述试验中,我们可以推出普通的一次输入,比如 输入一个 A
beforeTextChanged, s = 空串,start = 0, count = 0, after = 1
onTextChanged, s = A, start = 0, count = 1, before =0
其实就是上面的数字 3 改成了 数字 1. 
他们的区别就在于:
粘贴 是一次性输入3个字符
直接输入 是一次只能输入1个字符

再看Part 2, cm 被删除:
cmd
s start count after / before
s = cmd 0 2 a = 0
s = d 0 0 b = 2
s = d



beforeTextChanged:从start(=0) 位置开始,有count(=2)个字符将被长度为after(=0)的新文字所替换。 
-- 因为 cm 被删除,而 c 的位置是0,所以 start =0; 
-- “cm”的长度为2, 所以说我们理解为 有 2 个字符将被长度为 0 的新文字替换
-- 因为我们是纯删除的操作,所以 after, 也就是cm 被替换为的文字的长度是 0。

onTextChanged: 从start(=0) 位置开始,有count(=0)个字符刚刚替换了长度为before(=2)的旧文字。
-- 因为 cm 被删除,而 c 的位置是0,所以 start =0; 
-- 因为我们是纯删除的操作,旧文字 cm 被删除,所以被替换的文字,也就是 before = 2
-- 纯删除的操作,新文字是空串,所以是空串(count = 0的字符串)替换了 cm


// 试验2:

// 前提条件: EditText 中已经有 abcd 这4个字符

// Part 1: 选中 abc, 并删除

// Part 2: 粘贴 abc

// Part 3: 在 c 和 d 之间粘贴 1234 这4个字符

Android EditText TextWatcher 回调方法参数说明_第2张图片

// Part 1: 选中 abc, 并删除

纯删除操作,跟试验1的Part 2类似:
beforeTextChanged: 从start(=0) 位置开始,有count(=3)个字符将被长度为after(=0)的新文字所替换。 
-- abc, 位置是从0开始,3个字符被新的文字(空串)所替换

onTextChanged: 从start(=0) 位置开始,有count(=0)个字符刚刚替换了长度为before(=3)的旧文字
-- abc,位置是从0开始,(长度为0的)空串刚刚替换了 长度为3的旧文字 abc

// Part 2: 粘贴 abc
纯粘贴操作,跟试验1的Part 1类似:
beforeTextChanged: 从start(=0) 位置开始,有count(=0)个字符将被替换为长度为after(=3)的新文字。

onTextChanged: 从start(=0) 位置开始,有count(=3)个字符刚刚替换了长度为before(=0)的旧文字。

// Part 3: 在 c 和 d 之间粘贴 1234 这4个字符
纯粘贴操作,跟试验1的Part 1类似,但有一点不同的是:
1234 这几个字符的插入位置是在 abc 后面,
a, index = 0
b, index = 1
c, index = 2
所以 1234 是从 start = 3 的位置开始插入。
其他的参数:count / after; count / before 均与试验1的Part 1类似。

// 试验3:
// 前提条件:EditText 中已经有文字 ab1cd
// 试验场景:选中 b1c,然后输入 x

Test 3




ab1cd -- > axd

s start count after / before
beforeTextChanged  s = ab1cd 1 3 a = 1
onTextChanged  s = axd 1 1 b = 3
afterTextChanged  s = axd



这个场景跟试验1的Part 2类似,但有一点不同是:
试验1的Part 2是纯删除操作,
而这个场景是一个替换操作:
b1c 替换成了 "x".

beforeTextChanged: 从start(=1, b1c 中 b 的index = 1) 位置开始,有count(=3)个字符将被长度为after(=1)的新文字所替换。 
-- b1c, 位置是从1开始,3个字符被新的文字(x)所替换

onTextChanged: 从start(=1) 位置开始,有count(=1)个字符刚刚替换了长度为before(=3)的旧文字
-- b1c,位置是从1开始,长度为1的字符串 x 刚刚替换了 长度为3的旧文字 b1c

// 试验结束
// **************************************************************

希望我讲明白了这些参数的含义。
Android EditText TextWatcher 回调方法参数说明_第3张图片

你可能感兴趣的:(Android)