只是一个简单的Demo,EditText在Android中代表的往往是用户的输入结果,大多时候我们都直接getText获取文本数据,进行使用,但是在一些场景之下我们就需要监听EditText随时随地的变化,所以有addTextChangedListener的监听模式,内置前中后三个周期,让我们更加方便的使用和处理,下面请直接看Demo,非常简单 ~


  • Java 版本
  • 2017年 初版
  • 2018年 修订版(第一版)
  • 2018 修订版(第二版)
  • Kotlin版本


Java 版本

Effect 1

Android监听U盘数据加载 安卓监听文件变化_EditText

新手疑惑:为什么我们在onTextChanged中,进行了判空输出,一开始没有进行显示?

答疑:因为EditText的监听是从你输入开始算的,所以后面我们删除数据的时候就显示了我们之前判空的操作数据

2017年 初版

MainActivity

package com.example.dow.edittext;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private EditText mEt;
    private TextView mContent;
    private TextView mBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mEt = (EditText) findViewById(R.id.et);
        mContent = (TextView) findViewById(R.id.tv_content);
        mBtn = (TextView) findViewById(R.id.tv_btn);


        mEt.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if(TextUtils.isEmpty(charSequence)){
                    mContent.setText("木有变,木有变");
                }else{
                    mContent.setText("变化中,变化中");
                }
            }

            @Override
            public void afterTextChanged(Editable editable) {
                mBtn.setText( mEt.getText().toString().trim());
            }
        });
    }
}
2018年 修订版(第一版)

MainActivity (主要解决用户在输入中,我们一直动态监听,导致用户还没有输完而出现的数据错误,此处和上方效果图无关!!! )

package com.example.dow.edittext;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private EditText mEt;
    private TextView mContent;
    private TextView mBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mEt = (EditText) findViewById(R.id.et);
        mContent = (TextView) findViewById(R.id.tv_content);
        mBtn = (TextView) findViewById(R.id.tv_btn);


        mEt.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            //逻辑开始前,先移出监听
             mEt.removeTextChangedListener(this);

			/**
			* 在俩者区间进行逻辑处理,我这里是计算金额出现的问题,这样可以完美解决~
			*/

			//逻辑结束后,在加入监听
			mEt.addTextChangedListener(this);
            }

            @Override
            public void afterTextChanged(Editable editable) {
             
            }
        });
    }
}
2018 修订版(第二版)

场景:A、B俩个 EditText 各自计算,且相互影响

出现问题:A、B 因为相互影响,造成了死循环,导致内存溢出(简称:OOM

解决方案(以下代码,请看注释)

关于代码中用到的工具,如您需要具体代码,可通过这里进行查看!常用小工具!

/**
		* 首先要明白,关于监听,一次创建,终身使用的概念
		* 本文中keep2Decimal为设置用户只可以输入俩位小数
		* ToolUtil.convertToDouble 为String转double工具!
	    * ToolUtil.formatMoney(v1)为保留金钱格式
		*/
		//价格 A
		AEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                keep2Decimal(this, charSequence, AEditText);
            }

            @Override
            public void afterTextChanged(Editable editable) {
              //注意点1:这里判断有没有获取焦点至关重要!因为这样才能有效的避免AB死循环的开始!!!
                if (AEditText.hasFocus()) {
                    setPriceDate(1);
                }
            }
        });

        //价格 B
        BEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                keep2Decimal(this, charSequence, BEditText);
            }

            @Override
            public void afterTextChanged(Editable editable) {
	            //注意点1:这里判断有没有获取焦点至关重要!因为这样才能有效的避免AB死循环的开始!!!
                if (BEditText.hasFocus()) {
                    setPriceDate(2);
                }
            }
        });

	/**
	* 数据计算
	*/
    private void setPriceDate(int type) {
	    //这里的totalAmount是我模拟的一个总价
	    double totalAmount = 100.00;
	    
        double v1 = totalAmount - ToolUtil.convertToDouble(ToolUtil.getText(AEditText), 0);

        double v2 = totalAmount - ToolUtil.convertToDouble(ToolUtil.getText(BEditText), 0);
        if (type == 1) {
            BEditText.setText(ToolUtil.formatMoney(v1));
        } else {
            AEditText.setText(ToolUtil.formatMoney(v2));
        }
    }

activity_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context="com.example.dow.edittext.MainActivity">

    <EditText
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et"
        android:padding="8dp"
        />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:id="@+id/tv_content"
        />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:id="@+id/tv_btn"
         />
</LinearLayout>

Kotlin版本

仅简单记录俩者使用方式的不同

import android.text.Editable
  import android.text.TextWatcher

   etText.addTextChangedListener(object : TextWatcher{
   
     override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
     }

     override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
     }

     override fun afterTextChanged(s: Editable?) {
     }

  })