只是一个简单的Demo,EditText在Android中代表的往往是用户的输入结果,大多时候我们都直接getText获取文本数据,进行使用,但是在一些场景之下我们就需要监听EditText随时随地的变化,所以有addTextChangedListener的监听模式,内置前中后三个周期,让我们更加方便的使用和处理,下面请直接看Demo,非常简单 ~
- Java 版本
- 2017年 初版
- 2018年 修订版(第一版)
- 2018 修订版(第二版)
- Kotlin版本
Java 版本
Effect 1
新手疑惑:为什么我们在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?) {
}
})