Я работаю над Android-приложением, и у меня есть EditText, где пользователь может вводить числа. Я хочу отформатировать номер, используя разные форматы валют (например, ##, ##, ###), и я хочу сделать это «на лету», т.е. когда пользователь вводит каждую цифру (а не при нажатии на ввод). Я искал googled, и наткнулся на TextWatcher, который я впервые нашел многообещающим, но это оказалось абсолютной болью. Я отлаживаю свой код на телефоне HTC Desire, который имеет только мягкую клавиатуру.android EditText, клавиатура textWatcher проблема
Теперь я хочу получить обратный вызов, когда пользователь нажимает цифры (от 0 до 9), клавишу del (backspace) и вводит ключ. Из моего тестирования я нашел это (по крайней мере на моем телефоне)
1) EditText onKeyListener называется , когда пользователь нажимает дель или клавишу ввода. Когда пользователь нажимает enter, onKey функция вызывается дважды для одного введите (который, я считаю, предназначен для ACTION_UP и ACTION_DOWN). Когда пользователь нажимает del, onKey вызывается один раз (только для ACTION_DOWN), который я не знаю, почему. onKey никогда не вызывается, когда пользователь нажимает любые цифры (от 0 до 9), которые тоже я не могу понять.
2) TextWatchers 3 функции обратного вызова называются (beforeTextChanged, OnTextChanged, afterTextChanged) всякий раз, когда пользователь нажимает любую клавишу (число от 0 до 9). Поэтому я подумал, используя TextWatcher и onKeyListener вместе Я могу получить все обратные вызовы, в которых я нуждаюсь.
Теперь мои вопросы таковы ..
1) Во-первых, в моем HTC мягкой клавиатурой там является ключевым (символ клавиатуры с стрелкой вниз), и когда я нажимаю на него клавиатуры уходит в отставку без предоставления любого обратного вызова. Я все еще не могу поверить андроид позволяет пользователю редактировать поле и уйти в отставку без пропуска программы до процесс (сохранить) редактирования. Теперь мой EditText показывает одно значение, и мой объект имеет другое значение (я спасаю редактирует пользователей на въезд, и обращение назад нажмите на клавиатуре на переустановку значение EditText со значением в объекта, но у меня нет ответа к этому клавиатура вниз ключ).
2) Во-вторых, я хочу отформатировать номер после ввода пользователем новой цифры. Скажите У меня уже есть 123 на editText и пользователь вводил нажатый 4, мне нужен мой editText для отображения 1,234. Я получаю полный номер на onTextChanged() и afterTextChanged(), и я могу отформатировать номер и вернуть его обратно в editText в любом из этих обратных вызовов. Какой я должен использовать? Что является лучшей практикой ?
3) Третий - самая важная проблема . При запуске приложения я помещаю текущее значение объекта в editText. Скажем, я положил 123 на onResume(), и когда пользователь вводит цифру (скажем 4) Я хочу это быть 1234.Но на мой onTextChanged callback я получаю 4123. Когда нажимаю еще одну клавишу (скажем 5), я получаю 45123. Так что для пользовательских входов editText курсор указывает на конец текст. Но когда значение задано стороны, editText-курсор не кажется обновление. Я считаю, что мне нужно сделать что-то в текстовых обратных вызовах, но Я не знаю, что я должен делать.
Я отправляю свой код ниже.
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 дней. Я новичок в андроиде и все еще не могу поверить, что нет простого способа обрабатывать данные TextEdit на лету (я делал то же самое на iphone с легкостью). Спасибо всем
EDIT: после использования входного фильтра
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
Downvoter, пожалуйста, учтите, что комментарий – Krishnabhadra