Eu tenho um editText, o valor inicial é $ 0,00. Quando você pressiona 1, muda para $ 0,01. Pressione 4, ele vai para $ 0,14. Pressione 8, $ 1,48. Pressione backspace, $ 0,14, etc.
Isso funciona, o problema é, se alguém posicionar manualmente o cursor, ocorrem problemas na formatação. Se eles apagassem o decimal, ele não voltaria. Se eles colocarem o cursor na frente do decimal e digitarem 2, ele exibirá $ 02,00 em vez de $ 2,00. Se eles tentarem deletar $, um dígito será deletado, por exemplo.
Aqui está o código que estou usando. Agradeço todas as sugestões.
mEditPrice.setRawInputType(Configuration.KEYBOARD_12KEY);
public void priceClick(View view) {
mEditPrice.addTextChangedListener(new TextWatcher(){
DecimalFormat dec = new DecimalFormat("0.00");
@Override
public void afterTextChanged(Editable arg0) {
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@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]", "");
if (userInput.length() > 0) {
Float in=Float.parseFloat(userInput);
float percen = in/100;
mEditPrice.setText("$"+dec.format(percen));
mEditPrice.setSelection(mEditPrice.getText().length());
}
}
}
});
Respostas:
Testei seu método, mas ele falha quando uso grandes números ... Eu criei este:
fonte
String replaceable = String.format("[%s,.]", NumberFormat.getCurrencyInstance().getCurrency().getSymbol()); String cleanString = s.toString().replaceAll(replaceable, "");
String replaceable = String.format("[%s,.\\s]", NumberFormat.getCurrencyInstance().getCurrency().getSymbol());
onTextChanged() and rather to do so in
afterTextChanged () `double
10.10 / 100 = 0,1
você não pode passar por isso.Com base em algumas das respostas acima, criei um MoneyTextWatcher que você usaria da seguinte maneira:
e aqui está a classe:
fonte
java.lang.NumberFormatException: Bad offset/length
.replaceAll("[^0-9]", "")
, a acima tem um limite de 9.999.999 -_-Aqui está meu costume
CurrencyEditText
Use-o em XML como
Você deve editar 2 constantes abaixo para adequado para o seu projeto
Demo no github
fonte
formatter.setRoundingMode(RoundingMode.DOWN);
oformatDecimal
método.$.
, quando obtermos o valor bruto.
e analisarmos para Double, ele fornecerá NFE. Para consertar, fizformatDecimal()
para voltarprefix + "0.";
e mudei#,###.
para#,##0.
dentroformatDecimal()
. Isso também fica melhor quando o usuário insere apenas casas decimais. Mostra como em$0.25
vez de$.25
.Na verdade, a solução fornecida antes não está funcionando. Não funciona se você deseja inserir 100,00.
Substituir:
Com:
Devo dizer que fiz algumas modificações no meu código. A questão é que você deve usar o BigDecimal's
fonte
Eu mudo a classe com implementa TextWatcher para usar formatos de moeda do Brasil e ajustar a posição do cursor ao editar o valor.
fonte
Eu construí na resposta do Guilhermes, mas preservo a posição do cursor e também trato os pontos de forma diferente - desta forma, se um usuário estiver digitando após o ponto, não afeta os números antes do ponto. Acho que isso dá uma entrada muito suave .
fonte
Embora haja muitas respostas aqui, gostaria de compartilhar este código que encontrei aqui, pois acredito que seja a resposta mais robusta e limpa.
espero que ajude.
fonte
replaceAll("\\D", "")
irá remover tudo o que não for um dígito, portanto, "$ 100,00" e "$ 10.000" tornam-se "10.000". Parece que você está contando com a entrada para incluir centavos. Então, se isso for garantido, ótimo, mas se não, acho que haverá problemas.Ok, aqui está uma maneira melhor de lidar com formatos de moeda, pressionamento de tecla delete-backward. O código é baseado no código @androidcurious 'acima ... Mas, lida com alguns problemas relacionados à exclusão reversa e algumas exceções de análise: http://miguelt.blogspot.ca/2013/01/textwatcher-for-currency-masksformatting .html [ATUALIZAÇÃO] A solução anterior teve alguns problemas ... Esta é uma solução melhor: http://miguelt.blogspot.ca/2013/02/update-textwatcher-for-currency.html E ... aqui estão os detalhes:
Essa abordagem é melhor, pois usa os mecanismos convencionais do Android. A ideia é formatar valores depois que o usuário exista na Visualização.
Defina um InputFilter para restringir os valores numéricos - isso é necessário na maioria dos casos porque a tela não é grande o suficiente para acomodar longas visualizações de EditText. Pode ser uma classe interna estática ou apenas outra classe simples:
Defina uma classe (estática interna ou apenas uma classe) que implementará View.OnFocusChangeListener. Observe que estou usando uma classe Utils - a implementação pode ser encontrada em "Valores, impostos".
Esta classe removerá o formato da moeda durante a edição - contando com mecanismos padrão. Quando o usuário sai, o formato de moeda é reaplicado.
É melhor definir algumas variáveis estáticas para minimizar o número de instâncias:
Finalmente, dentro de onCreateView (...):
Você pode reutilizar FILTERS e ON_FOCUS em qualquer número de visualizações de EditText.
Aqui está a classe Utils:
fonte
Usei a implementação referenciada por Nathan Leigh e a regex sugerida por Kayvan N e user2582318 para remover todos os caracteres, exceto dígitos, para criar a seguinte versão:
Esta é uma função de extensão em Kotlin que adiciona o TextWatcher ao TextChangedListener do EditText.
Para usá-lo, basta:
Espero que ajude.
fonte
Eu peguei isso aqui e mudei para cumprir o formato da moeda portuguesa.
O layout.xml
Faça funcionar
fonte
Para mim funcionou assim
fonte
É melhor usar a interface InputFilter. Muito mais fácil de lidar com qualquer tipo de entrada usando regex. Minha solução para formato de entrada de moeda:
Válido: 0,00, 0,0, 10,00, 111,1
Inválido: 0, 0,000, 111, 10, 010,00, 01,0
Como usar:
fonte
Eu usei isso para permitir ao usuário inserir a moeda e convertê-la de string em int para armazenar no banco de dados e mudar de int para string novamente
https://github.com/nleigh/Restaurant/blob/master/Restaurant/src/uk/co/nathanleigh/restaurant/CurrencyFormat.java
fonte
Se o seu campo de moeda json for do tipo numérico (e não String), ele pode vir como 3.1, 3.15 ou apenas 3. Porque json arredonda campos numéricos automaticamente.
Nesse caso, você pode precisar arredondá-lo para uma exibição adequada (e para poder usar uma máscara em um campo de entrada posteriormente):
Por que isso é necessário?
Todas as respostas apontam para a remoção de símbolos monetários ao digitar, julgando que você está recebendo os centavos e formando dolar + centavos / 100 = dolar, centavos. Mas se o campo de moeda json for um tipo de número (e não uma string), ele arredondará seus centavos, pode ser 3, 3,1 ou 3,15.
fonte
come as 3.1 , 3.15 or just 3. Because json automatically round number fields
- isso não tem nada de comum com arredondamento !outra abordagem, mas baseada na resposta do Guilherme . Essa abordagem é útil quando a localidade do seu país não está disponível ou se você deseja usar símbolos de moeda personalizados. Esta implementação é apenas para números não decimais positivos.
este código está em Kotlin, primeiro delegado
setMaskingMoney
paraEditText
Então a
MyTextWatcher
interface deve ser estendida deTextWatcher
. Uma vez que precisamos apenas deafterTextChanged
método, os outros métodos precisam ser substituídos nesta interfacee os métodos de monetização são:
Implementações completas:
e em algum lugar no método onCreate:
fonte
Depois de muita pesquisa e falhas com Doubles, BigDecimals e assim por diante, eu fiz este código. Ele funciona plug and play. Está em kotlin. Então, para ajudar outras pessoas presas como eu, vamos.
O código é basicamente uma função que colocará um textWatcher e ajustará a coma no lugar certo.
Primeiro, crie esta função:
E então você chama esta função desta forma
fonte
Depois de olhar para a maioria das mensagens StackOverflow sobre diferentes maneiras de conseguir isso usando um
TextWatcher
,InputFilter
ou biblioteca como CurrencyEditText eu tenha resolvido em esta solução simples usando umOnFocusChangeListener
.A lógica é analisar o
EditText
para um número quando estiver focado e formatá-lo de volta quando perder o foco.fonte
Implementei uma versão Kotlin + Rx.
É para a moeda brasileira (por exemplo, 1.500,00 - 5,21 - 192,90), mas você pode facilmente adaptar para outros formatos.
Espero que outra pessoa ache útil.
fonte
CurrencyTextWatcher.java
EditTextCurrency.java
fonte
Aqui está como eu consegui exibir uma moeda em um EditText que era fácil de implementar e funciona bem para o usuário sem o potencial de símbolos malucos por todo o lugar. Isso não tentará fazer nenhuma formatação até que EditText não tenha mais o foco. O usuário ainda pode voltar e fazer qualquer edição sem comprometer a formatação. Eu uso a variável 'formattedPrice' apenas para exibição e a variável 'itemPrice' como o valor que armazeno / uso para cálculos.
Parece que está funcionando muito bem, mas só estou nisso há algumas semanas, então qualquer crítica construtiva é absolutamente bem-vinda!
A visualização EditText no xml tem o seguinte atributo:
Variáveis globais:
No método onCreate:
fonte
Caso alguém esteja interessado em uma maneira de fazer isso usando RxBinding e Kotlin:
fonte
apenas um comentário adicional à resposta aprovada. Você pode obter uma falha ao mover o cursor no campo de texto de edição devido à análise. Fiz uma instrução try catch, mas implemente seu próprio código.
fonte
você pode usar esses métodos
fonte
Versão Kotlin :
fonte
e então use este bloco como seu editText
fonte
Esta é a resposta de Saeid Mohammadi, mas mudei para aceitar números negativos.
fonte