Как вы создаете запись edittext, которая форматирует ввод только в денежном формате? Когда пользователь вводит 5, я хочу, чтобы ввод выглядел как «0,05 доллара», а когда он затем вводит 3, ввод теперь должен выглядеть как «0,53 доллара», и, наконец, он вводит 6, а ввод должен выглядеть как «5,36 доллара».
Ввод денег Android с фиксированным десятичным числом
Ответы (7)
Полное решение ninjasense в основном работает, но у него есть некоторые проблемы:
- Каждый раз, когда данные поля изменяются в обработчике onTextChanged, позиция курсора сбрасывается до индекса 0 в поле, что немного раздражает при вводе денежных значений.
- Он использует числа с плавающей запятой для форматирования денежных значений, что может иметь неприятные последствия.
Для первой проблемы у меня еще нет решения, для второй работает такой код:
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(!s.toString().matches("^\\$(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$"))
{
String userInput= ""+s.toString().replaceAll("[^\\d]", "");
StringBuilder cashAmountBuilder = new StringBuilder(userInput);
while (cashAmountBuilder.length() > 3 && cashAmountBuilder.charAt(0) == '0') {
cashAmountBuilder.deleteCharAt(0);
}
while (cashAmountBuilder.length() < 3) {
cashAmountBuilder.insert(0, '0');
}
cashAmountBuilder.insert(cashAmountBuilder.length()-2, '.');
cashAmountBuilder.insert(0, '$');
cashAmountEdit.setText(cashAmountBuilder.toString());
}
}
Строительство Zds.
Используйте это для удержания курсора в конце поля.
cashAmountEdit.setTextKeepState(cashAmountBuilder.toString());
Selection.setSelection(cashAmountEdit.getText(), cashAmountBuilder.toString().length());
Вы можете использовать TextWatcher, чтобы делать такие вещи.
Расширение TextWatcher: http://d.android.com/reference/android/text/TextWatcher.html
public class MyTextWatcher implements TextWatcher {
public void afterTextChanged(Editable arg0) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
}
Затем добавьте его в свой editText с помощью
myEditText.addTextChangedListener(new MyTextWatcher());
Я нашел TextWatcher немного громоздким. Вместо этого вы можете установить прослушиватель ключей:
setKeyListener(new CalculatorKeyListener());
// Must be called after setKeyListener(), otherwise is overridden
setRawInputType(Configuration.KEYBOARD_12KEY);
А затем создайте KeyListener, который расширяет NumberKeyListener:
class CalculatorKeyListener extends NumberKeyListener {
@Override
public int getInputType() {
return InputType.TYPE_CLASS_NUMBER;
}
@Override
public boolean onKeyDown(View view, Editable content, int keyCode, KeyEvent event) {
if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
digitPressed(keyCode - KeyEvent.KEYCODE_0);
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
deletePressed();
}
return true;
}
@Override
protected char[] getAcceptedChars() {
return new char[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
}
}
Затем вам нужно правильно отобразить символы, но это несложно; просто следите за центами, а затем разделите или умножьте на 10 и используйте NumberFormat, чтобы получить правильное форматирование.
Вот мое полное решение:
tvValue.setRawInputType(Configuration.KEYBOARD_12KEY);
tvValue.addTextChangedListener(new TextWatcher(){
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
// TODO Auto-generated method stub
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
// TODO Auto-generated method stub
// here i converted to string
if(!s.toString().matches("^\\$(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$"))
{
String userInput= ""+s.toString().replaceAll("[^\\d]", "");
Float in=Float.parseFloat(userInput);
float percen = in/100;
tvValue.setText("$"+percen);
}
}
});
Я сделал это, но без десятичных знаков и с точкой для миль, проверьте код и добавьте функциональность для поддержки десятичных знаков.
MyEditText.addTextChangedListener(new TextWatcher()
{
@Override
public void onTextChanged(CharSequence s, int start, int before, int count){
if(s.toString().length() > 0){
MyEditText.removeTextChangedListener(this);
String numbers = removeCharacters(s.toString());
int money = 0;
try{
money = Integer.parseInt(numbers);
}
catch(Exception ex){
money = 0;
}
MyEditText.setText(getMoney(money));
//Set cursor on correct position
int selection = start;
if(count > 0){
selection++;
if(MyEditText.getText().toString().length() == 2 || MyEditText.getText().toString().length() == 6 || MyEditText.getText().toString().length() == 10){
selection++;
}
}
else{
if(MyEditText.getText().toString().length() == 4 || MyEditText.getText().toString().length() == 8){
selection--;
}
}
if(selection > MyEditText.getText().toString().length()){
selection = MyEditText.getText().toString().length();
}
MyEditText.setSelection(selection);
MyEditText.addTextChangedListener(this);
}
if(s.toString().length() == 1 && count < 1 && start == 1){
MyEditText.removeTextChangedListener(this);
MyEditText.setText("");
MyEditText.addTextChangedListener(this);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after){
}
@Override
public void afterTextChanged(Editable s)
{
}
});
public String removeCharacters(String money){
int i=0;
while (i<money.length())
{
Character c = money.charAt(i);
if (Character.isDigit(c) && c != '.')
{
i++;
}
else
{
money = money.replace(c.toString(), "");
}
}
return money;
}
public String getMoney(int value){
String money = "$";
NumberFormat numberFormatter;
numberFormatter = NumberFormat.getNumberInstance(Locale.GERMAN);
money += numberFormatter.format(value);
return money;
}
Этот ответ основан на ответе Zds (который, в свою очередь, основан на ответ ninjasense), но это должно решить проблему с положением курсора:
if(!text.matches("^\\$(\\d{1,2})(\\.\\d{2})?$")) {
int originalCursorPosition = view.getSelectionStart();
int cursorOffset = 0;
boolean cursorAtEnd = originalCursorPosition == text.length();
String userInput= ""+text.replaceAll("[^\\d]", "");
StringBuilder cashAmountBuilder = new StringBuilder(userInput);
while (cashAmountBuilder.length() > 3 && cashAmountBuilder.charAt(0) == '0') {
cashAmountBuilder.deleteCharAt(0);
cursorOffset--;
}
while (cashAmountBuilder.length() < 3) {
cashAmountBuilder.insert(0, '0');
cursorOffset++;
}
cashAmountBuilder.insert(cashAmountBuilder.length() - 2, '.');
cashAmountBuilder.insert(0, '$');
view.setText(cashAmountBuilder.toString());
view.setSelection(cursorAtEnd ? view.getText().length() : originalCursorPosition + cursorOffset);
}
Примечания:
- Следующее находится в
TextWatcher.onTextChanged
- Я использую регулярное выражение, отличное от других ответов, что удерживает цену на уровне ‹ 100 долларов.
- 'view' - это editText, 'text' - это содержимое строки
- это сработало для меня, используя
EditText
сmaxLength
из 6 (т.е. 00,00 долларов США)