¿Cómo se crea una entrada de texto de edición que formatea la entrada solo en formato de dinero? Cuando el usuario ingresa 5, quiero que la entrada se vea como "$ 0.05" y cuando luego ingrese 3, la entrada debe verse como "$ 0.53" y finalmente ingresan 6 y la entrada debe verse como "$ 5.36".Android Money Input con decimal fijo
Respuesta
Puede usar un TextWatcher para hacer ese tipo de cosas.
Extender 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) {
}
}
después añadirlo a su EDITTEXT con
myEditText.addTextChangedListener(new MyTextWatcher());
encontré el TextWatcher a ser un poco engorroso. En su lugar, se puede establecer el detector de teclas:
setKeyListener(new CalculatorKeyListener());
// Must be called after setKeyListener(), otherwise is overridden
setRawInputType(Configuration.KEYBOARD_12KEY);
y luego crear un KeyListener que se extiende 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 };
}
}
A continuación, deberá mostrar los caracteres correctamente, pero eso no es difícil; solo haga un seguimiento de los centavos, y luego divida o multiplique por 10, y use un NumberFormat para obtener el formato correcto.
Aquí está mi solución completa: solución completa
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);
}
}
});
de ninjasense trabaja básicamente, pero tiene algunos problemas:
- Cada vez que los datos del campo se altera en el "OnTextChanged" manipulador, la posición del cursor se restablece al índice 0 en el campo, lo cual es un poco molesto cuando se ingresan los valores monetarios.
- Utiliza flotadores para formatear valores monetarios, lo que puede ser contraproducente.
Para el primer problema que no tengo solución, sin embargo, para el segundo código como este funciona:
@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());
}
}
Construido a partir zds.
Para mantener el cursor al final del campo, utilícelo.
cashAmountEdit.setTextKeepState(cashAmountBuilder.toString());
Selection.setSelection(cashAmountEdit.getText(), cashAmountBuilder.toString().length());
Hice esto pero sin decimal y con punto por millas, verifique el código y agregue la funcionalidad para admitir decimales.
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;
}
Esta respuesta se basa en Zds' answer (que a su vez se basa en ninjasense's answer), pero esto debería resolver el problema posición del cursor:
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);
}
Notas:
- El siguiente es en un
TextWatcher.onTextChanged
- Estoy usando un diferente expresiones regulares que otras respuestas, que mantiene el precio a $ 100 <
- 'vista' es la EDITTEXT, 'texto' es el contenido de la cadena
- esto ha funcionado para mí utilizando un
EditText
con unmaxLength
de 6 (es decir, $ 00,00)
- 1. Android EditText con un sufijo fijo
- 2. Punto decimal o coma decimal en Android
- 3. En SQL, ¿cómo puedo convertir un tipo de datos money a decimal?
- 4. Android Limitar EditText to Integer input only
- 5. Encabezado fijo con jquery
- 6. Posicionamiento fijo con desplazamiento
- 7. Rails money gem and form builder
- 8. Google Chrome en Android (y solo Android) No permite Decimal con tipo número y paso = "cualquiera"
- 9. Fracciones con precisión decimal
- 10. Android: fuente de ancho fijo en AlertDialog
- 11. Esquema XML para un elemento fijo con un atributo fijo?
- 12. ¿El tipo de datos "MONEY" de SQL Server es un punto flotante decimal o un punto flotante binario?
- 13. C#: ¿Multiplicar decimal con flotador?
- 14. Teclado numérico con separador decimal
- 15. Configuración de la moneda con el formulario de selección con Money gem
- 16. Cómo convertir de una cadena a un número en Oracle utilizando la función TO_NUMBER con un punto decimal fijo char?
- 17. Diferencia entre decimal y decimal
- 18. formato de cuadro de texto C# decimal
- 19. En Android, ¿cómo crear EditText de ancho fijo?
- 20. input type = "submit" en lugar de input type = "button" con AJAX?
- 21. Punto flotante o punto fijo para aplicaciones Android NDK OpenGL?
- 22. zócalo RFCOMM de Android en el canal fijo
- 23. comparar un NSNumber con un valor fijo?
- 24. Tabla con columnas dinámicas pero diseño fijo
- 25. Fuentes con verdadero ancho fijo en WPF
- 26. div no seleccionable con posición: fijo
- 27. UILabel con ancho fijo y altura flexible
- 28. UIButton imagen personalizada tamaño fijo con
- 29. Resolver esta ecuación con punto fijo iteración
- 30. Sanitizing Integer Database Input
KeyListener ya no funciona en algunos dispositivos, consulte esta nota: Las pulsaciones de teclas en los métodos de entrada suaves no son necesarios para activar los métodos de este oyente, y son, de hecho, desaniman a hacerlo. El teclado predeterminado de Android no los desencadenará para ninguna tecla de ninguna aplicación que apunte a Jelly Bean o más tarde, y solo lo entregará para algunas pulsaciones de teclas a las aplicaciones dirigidas a Ice Cream Sandwich o antes. Fuente: http://developer.android.com/reference/android/text/method/KeyListener.html –