【发布时间】:2011-08-04 11:00:01
【问题描述】:
我正在开发一个 android 应用程序,并且我有一个 EditText,用户可以在其中输入数字。我想使用不同的货币格式(比如##、##、###)来格式化数字,并且我想即时进行,即当用户输入每个数字时(而不是按下输入时)。我四处搜索,发现了TextWatcher,我首先发现它很有希望,但结果证明这绝对是一种痛苦。我正在一台只有软键盘的 HTC Desire 手机上调试我的代码。
现在我想在用户按下数字(0 到 9)、del(退格)键和 enter 键时获得回调。从我的测试中我发现了这些(至少在我的手机上)
1) 调用editText onKeyListener 当用户按 del 或 enter 键时。 当用户按下回车键时,onKey 一次输入调用两次函数 (我相信这是 ACTION_UP 和 ACTION_DOWN)。当用户按下 del 时, onKey 被调用一次(仅适用于 ACTION_DOWN) 我不知道为什么。 用户时永远不会调用 onKey 按下任何数字(0 到 9),这也是我 无法理解。
2) TextWatchers 3个回调函数 被称为(在TextChanged之前, onTextChanged, afterTextChanged) 每当用户按下任何数字(0 到 9) 键。所以我想通过使用 TextWatcher 和 onKeyListener 在一起 我可以得到我需要的所有回调。
现在我的问题是这些..
1) 首先在我的 HTC 软键盘那里 是一个键(带有 向下箭头),当我点击它时 键盘辞职不给 任何回调。我还是不敢相信 android让用户编辑字段 并辞职不让程序 处理(保存)编辑。现在我的 editText 显示一个值,而我的 对象有另一个值(我正在保存 用户在输入时进行编辑,并处理回 通过重置按下键盘 editText 值与中的值 对象,但我对此没有答案 键盘向下键)。
2) 二、我要格式化数字 用户输入新数字后。说 我已经有 123 在 editText 和 用户输入按下 4,我想要我的 editText 显示 1,234。我吃饱了 onTextChanged() 和 afterTextChanged() 我可以格式化 号码并将其放回 任何这些回调中的editText。 我应该使用哪一个?哪一个是 最佳实践?
3) 第三个是最关键的 问题。当应用程序启动时,我把 editText 中的当前对象值。 假设我在 onResume() 上放了 123,当 用户输入一个数字(比如 4)我想要它 是 1234。但在我的 onTextChanged 回调我得到的是4123。当 我再按一个键(比如 5) 我是 得到 45123。所以对于用户输入 editText 光标指向末尾 文本。但是当值由 手,editText 光标似乎不是 更新。我相信我必须做 textWatcher 回调中的某些内容,但是 我不知道我该怎么办。
我在下面发布我的代码。
public class AppHome extends AppBaseActivity {
private EditText ed = null;
private NumberFormat amountFormatter = null;
private boolean isUserInput = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_home_screen);
ed = (EditText)findViewById(R.id.main_amount_textfield);
amountFormatter = new DecimalFormat("##,##,###");
ed.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN)
return true;
String strippedAmount = ed.getText().toString().replace(",", "");
if(keyCode == KeyEvent.KEYCODE_DEL){
//delete pressed, strip number of comas and then delete least significant digit.
strippedAmount = strippedAmount.substring(0, strippedAmount.length() - 1);
int amountNumeral = 0;
try{
amountNumeral = Integer.parseInt(strippedAmount);
} catch(NumberFormatException e){
}
myObject.amount = amountNumeral;
isUserInput = false;
setFormattedAmount(amountNumeral,ed.getId());
}else if(keyCode == KeyEvent.KEYCODE_ENTER){
//enter pressed, save edits and resign keyboard
int amountNumeral = 0;
try{
amountNumeral = Integer.parseInt(strippedAmount);
} catch(NumberFormatException e){
}
myObject.amount = amountNumeral;
isUserInput = false;
setFormattedAmount(myObject.amount,ed.getId());
//save edits
save();
//resign keyboard..
InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
in.hideSoftInputFromWindow(AppHome.this.getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
}
return true;
}
});
TextWatcher inputTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
if(isUserInput == false){
//textWatcher is recursive. When editText value is changed from code textWatcher callback gets called. So this variable acts as a flag which tells whether change is user generated or not..Possibly buggy code..:(
isUserInput = true;
return;
}
String strippedAmount = ed.getText().toString().replace(",", "");
int amountNumeral = 0;
try{
amountNumeral = Integer.parseInt(strippedAmount);
} catch(NumberFormatException e){
}
isUserInput = false;
setFormattedAmount(amountNumeral,ed.getId());
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
ed.addTextChangedListener(inputTextWatcher);
}//end of onCreate...
public void setFormattedAmount(Integer amount, Integer inputBoxId){
double amountValue = 0;
String textString =null;
TextView amountInputBox = (TextView) findViewById(inputBoxId);
amountValue = Double.parseDouble(Integer.toString(amount));
textString = amountFormatter.format(amountValue).toString();
amountInputBox.setText(textString);
}
}
我知道这是一个大问题,但我正在处理同样的问题 2 天。我是 android 新手,仍然无法相信没有简单的方法可以即时处理 textEdit 数据(我在 iphone 上轻松地做了同样的事情)。谢谢大家
编辑:使用输入过滤器后
InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String strippedAmount = dest.toString() + source;
strippedAmount = strippedAmount.replace(",", "");
int amountNumeral = 0;
try{
amountNumeral = Integer.parseInt(strippedAmount);
} catch(NumberFormatException e){
}
return amountFormatter.format(amountNumeral).toString();
}
};
ed.setFilters(new InputFilter[]{filter});
当应用启动时,我将 1,234 放在 editText 上
myObject.amount = 1234;
ed.setText(amountFormatter.format(myObject.amount).toString());
然后当用户点击editText时,键盘弹出,说用户输入数字6
我得到:61234 我想要: 12346
【问题讨论】:
标签: android android-edittext formatter textwatcher