我的Android应用程序中有3个EditText字段,我正在尝试彼此通信。它们是订单总额,收到的金额和小费。用户在第一个EditText中输入订单的价格。另外两个EditTexts是我想根据每个EditTexts的值修改的。如果用户在订单总数中输入20.00,在收到的金额中输入25.00,我希望提示显示5.00。同样,如果他们在订单总数中输入20.00,在提示中输入5.00,我希望收到的金额显示为25.00。我的所有计算都是正确的,只要另一个被注释掉,我的TextWatchers中的每一个都可以工作,但是对于它们两者,它只会创建一个无限循环。有没有一个很好的方法来做到这一点,或者有人可以指出我正确的方向一些有用的链接?我似乎找不到任何可行的工作。
我的代码如下:
eTotalCost = (EditText) findViewById(R.id.orderTotal);
eAmountReceived = (EditText) findViewById(R.id.amountReceived);
eTip = (EditText) findViewById(R.id.tip);
eMileage = (EditText) findViewById(R.id.mileage);
eGrandTotal = (EditText) findViewById(R.id.grandTotal);
eAmountReceived.addTextChangedListener(new TextWatcher()
{
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after){}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count){}
@Override
public void afterTextChanged(Editable s)
{
eAmountReceived = (EditText) findViewById(R.id.amountReceived);
eTotalCost = (EditText) findViewById(R.id.orderTotal);
eTip = (EditText) findViewById(R.id.tip);
eMileage = (EditText) findViewById(R.id.mileage);
eGrandTotal = (EditText) findViewById(R.id.grandTotal);
sAmountReceived = eAmountReceived.getText().toString();
sTotalCost = eTotalCost.getText().toString();
sMileage = eMileage.getText().toString();
sTip = eTip.getText().toString();
try
{
dAmountReceived = Double.parseDouble(sAmountReceived);
dTotalCost = Double.parseDouble(sTotalCost);
dSubtract = dAmountReceived - dTotalCost;
dMileage = Double.parseDouble(sMileage);
dGrandTotal = dSubtract + dMileage;
} catch(NumberFormatException e){}
sTip = String.valueOf(dSubtract);
DecimalFormat df = new DecimalFormat("0.00");
sTip = df.format(dSubtract);
eTip.setText(sTip);
sGrandTotal = String.valueOf(dGrandTotal);
sGrandTotal = df.format(dGrandTotal);
eGrandTotal.setText(sGrandTotal);
}
});
eTip.addTextChangedListener(new TextWatcher()
{
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after){}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count){}
@Override
public void afterTextChanged(Editable s) {
eAmountReceived = (EditText) findViewById(R.id.amountReceived);
eTotalCost = (EditText) findViewById(R.id.orderTotal);
eTip = (EditText) findViewById(R.id.tip);
eMileage = (EditText) findViewById(R.id.mileage);
eGrandTotal = (EditText) findViewById(R.id.grandTotal);
sAmountReceived = eAmountReceived.getText().toString();
sTotalCost = eTotalCost.getText().toString();
sMileage = eMileage.getText().toString();
sTip = eTip.getText().toString();
try
{
dTip = Double.parseDouble(sTip);
dTotalCost = Double.parseDouble(sTotalCost);
dAdd = dTotalCost + dTip;
dMileage = Double.parseDouble(sMileage);
dGrandTotal = dTip + dMileage;
} catch (NumberFormatException e) {}
sAmountReceived = String.valueOf(dAdd);
DecimalFormat df = new DecimalFormat("0.00");
sAmountReceived = df.format(dAdd);
eAmountReceived.setText(sAmountReceived);
sGrandTotal = String.valueOf(dGrandTotal);
sGrandTotal = df.format(dGrandTotal);
eGrandTotal.setText(sGrandTotal);
}
});
答案 0 :(得分:2)
您正在使用afterTextChanged回调
循环setText方法发生了什么:
您有2个textWatchers:一个用于eTip
,另一个用于eAmountReceived
当您在其中任何一个字段上调用setText()
时,它将开始循环播放,因为setText将触发afterTextChanged
,并且在您的两个文本观察者中,您正在调用setText()
的相反字段,再次,将触发afterTextChanged
为了避免这种情况,引入一些布尔标志,表示已经为各个edittext设置了值,或者只有当新值与之前设置的值不同时才调用setText
答案 1 :(得分:1)
首先删除afterTextChanged中的findviewbyid代码。您无需在每次使用中声明它们。只能在onCreate中使用。
对于您的问题,最简单的解决方案是将TextWatchers保存在类中声明的变量中。然后在每次调用setText()之前,为所有textWatchers调用removeTextChangeListener,并在setText()之后重新添加textWatchers。
编辑:不删除并重新添加所有setText()调用。只在条件循环中执行。
答案 2 :(得分:0)
在尝试创建货币转换器应用时,我遇到了同样的问题。 (editText 1中的更改值应更改editText 2中的值,反之亦然)。
我解决这个问题的方法是创建两个文本观察者。
private TextWatcher TextWatcherClass = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
editText2.removeTextChangedListener(TextWatcherClass2);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
editText2.addTextChangedListener(TextWatcherClass2);
}
};
private TextWatcher TextWatcherClass2 = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
editText1.removeTextChangedListener(TextWatcherClass);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
editText1.addTextChangedListener(TextWatcherClass);
}
};
希望这有帮助。