android - TextWatcher 的 onTextChanged、beforeTextChanged 和 afterTextChanged 的​​区别

标签 android textwatcher android-textwatcher

在我的 Android 项目中,我不得不将 TextChangedListener (TextWatcher) 添加到编辑 TextView 中。它分为三个部分:

  • onTextChanged()
  • beforeTextChanged()
  • afterTextChanged()

这三个有什么区别?我不得不在关键监听器上实现对表的搜索,就我而言,这三个看起来都一样。它们的功能也相同。当我输入产品名称的一部分时,表格会重新绘制仅包含其中包含输入文本的那些产品。但我使用了 afterTextChanged() 部分。我的代码是:

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);
            }
        }
    });

那么有人可以给我解释一下这三个吗?

最佳答案

beforeTextChangedonTextChanged的参数一开始有点难理解。在示例中使用它们可能会有所帮助。多看几次下面的演示。注意计数。

  • 红色突出显示的是即将被绿色文本替换的旧文本。
  • 绿色突出显示的是刚刚替换红色文本的新文本。

enter image description here

beforeTextChanged

  • start是红色高亮文本(即将被删除)的起始索引
  • count红色 突出显示的文本(即将被删除)的长度
  • after绿色高亮文本的长度(即将添加)

onTextChanged

  • start 是绿色突出显示文本(刚刚添加)的开始索引。
    这与 beforeTextChangedstart 相同。
  • beforered 突出显示的文本(刚刚被删除)的长度。
    这与 beforeTextChangedcount 相同。
  • countgreen 突出显示的文本(刚刚添加)的长度。
    这与 beforeTextChangedafter 相同。

afterTextChanged

  • editable 是来自 EditText 的可编辑文本。您可以在此处更改它。这样做会再次触发所有 TextWatcher 事件。
  • 没有向您提供有关更改内容的任何信息。如果你想知道,你可以在onTextChanged中设置一个span,然后在这里查找span。

什么时候用哪个?

如果您想观察所做的更改,请使用 beforeTextChanged()onTextChanged()。但是,您不能在这两种方法中更改 CharSequence 文本。

如果您想在更改后进一步修改文本,请在 afterTextChanged() 中进行。

代码

如果你想自己玩,这里是代码。

MainActivity.java

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

<?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>

关于android - TextWatcher 的 onTextChanged、beforeTextChanged 和 afterTextChanged 的​​区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20278382/

相关文章:

android - 最小日期最大日期在 xamarin android 中不起作用

android - 使用 setText() 不想调用 textwatcher 事件?

java - 如何在 GWT 中将自定义 HTML 元素注册为小部件

android - GridLayout(不是GridView)如何均匀拉伸(stretch)所有 child

java - 如何使用TextWatcher自动从edittext中获取值并相乘?

android - textwatcher 上的 IndexOutOfBoundsException

java - 尝试在具有 TextChangedListener 的 edittext 上输入时应用程序崩溃

java - 可能到 'layer' Android 应用程序?

android - TextWatcher 不工作,出了什么问题