Differences between TextWatcher 's onTextChanged, beforeTextChanged and afterTextChanged
在我的Android项目中,我必须将TextChangedListener(TextWatcher)添加到编辑文本视图。 它包括三个部分:
-
onTextChanged() -
beforeTextChanged() -
afterTextChanged()
这三个有什么区别? 我不得不在键侦听器上实现对表的搜索,对于我来说,这三个表看起来都一样。 它们的功能也相同。 当我输入一部分产品名称时,该表将仅使用其中包含输入文字的那些产品进行重绘。 但是我使用了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | EditProduct.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO Auto-generated method stub // System.out.println("onTextChanged"+s); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub // System.out.println("beforeTextChanged"+s); } @Override public void afterTextChanged(Editable s) { // TODO Auto-generated method stub // System.out.println("afterTextChanged"+s); String new_prx = s.toString(); System.out.println(s); mini_productList = new ArrayList<Product>(); // mini_productList int count = 0; if (new_prx.equals("")) { loadtableProducts(productList); } else { for (int i = 0; i < productList.size(); i++) { if (productList.get(i).getDescription().toString() .substring(0, (new_prx.length())) .equalsIgnoreCase(new_prx)) { mini_productList.add(productList.get(i)); count++; } } loadtableProducts(mini_productList); } } }); |
那么有人可以给我解释这三个方面吗?
首先,很难理解
- 红色突出显示是即将被绿色文本替换的旧文本。
- 绿色突出显示的是新文本,仅替换了红色文本。
beforeTextChanged
-
start 是红色突出显示的文本(即将被删除)的起始索引 -
count 是红色突出显示的文本的长度(即将被删除) -
after 是绿色突出显示的文本的长度(即将添加)
onTextChanged
-
start 是绿色突出显示的文本(刚刚添加)的起始索引。
这与beforeTextChanged 的start 相同。 -
before 是红色突出显示的文本(刚删除的文本)的长度。
这与beforeTextChanged 的count 相同。 -
count 是绿色突出显示的文本(刚刚添加)的长度。
这与beforeTextChanged 的after 相同。
afterTextChanged
-
editable 是EditText中的可编辑文本。您可以在这里更改它。这样做将再次触发所有TextWatcher 事件。 -
您未获得有关更改内容的任何信息。如果您想知道,可以在
onTextChanged 中设置一个跨度,然后在此处查找该跨度。
什么时候使用?
如果要观察所做的更改,请使用
如果要在更改后进一步修改文本,请在
码
如果您想自己玩,这里是代码。
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | public class MainActivity extends AppCompatActivity { final static int RED_COLOR = Color.parseColor("#fb7373"); final static int GREEN_COLOR = Color.parseColor("#40de83"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EditText editText = findViewById(R.id.editText); final TextView tvBeforeText = findViewById(R.id.tvBeforeText); final TextView tvBeforeNumbers = findViewById(R.id.tvBeforeNumbers); final TextView tvAfterText = findViewById(R.id.tvAfterText); final TextView tvAfterNumbers = findViewById(R.id.tvAfterNumbers); editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { SpannableString spannableString = new SpannableString(s); BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(RED_COLOR); spannableString.setSpan(backgroundSpan, start, start + count, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); tvBeforeText.setText(spannableString); tvBeforeNumbers.setText("start=" + start +" count=" + count +" after=" + after); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { SpannableString spannableString = new SpannableString(s); BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(GREEN_COLOR); spannableString.setSpan(backgroundSpan, start, start + count, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); tvAfterText.setText(spannableString); tvAfterNumbers.setText("start=" + start +" before=" + before +" count=" + count); } @Override public void afterTextChanged(Editable s) { Log.i("TAG","afterTextChanged:" + s); } }); } } |
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp"> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:text="beforeTextChanged" /> <TextView android:id="@+id/tvBeforeText" android:textSize="17sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/tvBeforeNumbers" android:textSize="17sp" android:text="start=0 count=0 after=0" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:layout_marginTop="20dp" android:text="onTextChanged" /> <TextView android:id="@+id/tvAfterText" android:textSize="17sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/tvAfterNumbers" android:textSize="17sp" android:text="start=0 count=0 after=0" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> |
根据您要分配变量或执行操作的时间,可能要在更改之前或之后运行代码。
这是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | String afterTextChanged =""; String beforeTextChanged =""; String onTextChanged =""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et = (EditText)findViewById(R.id.editText); et.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int st, int b, int c) { onTextChanged = et.getText().toString(); } @Override public void beforeTextChanged(CharSequence s, int st, int c, int a) { beforeTextChanged = et.getText().toString(); } @Override public void afterTextChanged(Editable s) { afterTextChanged = et.getText().toString(); Toast.makeText(Activity.this,"before:" + beforeTextChanged + ' ' +"on:" + onTextChanged + ' ' +"after:" + afterTextChanged ,Toast.LENGTH_SHORT).show(); } }); } |
在这种情况下,假设您将文本从" h"更改为" hi",输出将是:
before:"h"
on:"hi"
after:"hi"
Android
1.beforeTextChanged:这意味着字符将被一些新文本替换。文本不可编辑。当您需要查看将要更改的旧文本时,将使用此事件。
2.onTextChanged:已进行更改,某些字符刚刚被替换。文本不可编辑。当您需要查看文本中的哪些字符是新字符时,将使用此事件。
3.afterTextChanged:与上面相同,除了现在文本是可编辑的。当您需要查看并可能编辑新文本时,将使用此事件。
abstract void afterTextChanged(Editable s) This method is called to notify you that, somewhere within s, the
text has been changed.
abstract void beforeTextChanged(CharSequence s, int start, int count,
int after)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 length after.
abstract void onTextChanged(CharSequence s, int start, int before, int count) This method is called to notify you that, within s, the count
characters beginning at start have just replaced old text that had
length before.
您可以在此处了解更多信息。
afterTextChanged (Editable s) - This method is called when the text has been changed. Because any changes you make will cause this
method to be called again recursively, you have to be watchful about
performing operations here, otherwise it might lead to infinite loop.beforeTextChanged (CharSequence s, int start, int count, int after) - 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 length after. It is an error to attempt to make changes to s from
this callback.onTextChanged (CharSequence s, int start, int before, int count) - This method is called to notify you that, within s, the count
characters beginning at start have just replaced old text that had
length before. It is an error to attempt to make changes to s from
this callback.