Last active
October 9, 2018 20:07
-
-
Save tucomel/d23e27fbdb246ea31cc511ee3fb59795 to your computer and use it in GitHub Desktop.
MoneyTextWatcher Android
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MoneyTextWatcher extends METValidator implements TextWatcher, View.OnFocusChangeListener { | |
public static final String T = "MoneyTextWatcher"; | |
protected int max_length = Integer.MAX_VALUE; | |
private EditText editText; | |
private View linkedText; | |
private String formatType; | |
private String current = ""; | |
private boolean insertingSelected = false; | |
private boolean isDeleting; | |
private MoneyTextDelegate delegate; | |
public interface MoneyTextDelegate { | |
void afterTextChanged(Editable s); | |
void beforeTextChanged(CharSequence s, int start, int count, int after); | |
void onFocusChange(View v, boolean hasFocus); | |
void onTextChanged(CharSequence s, int start, int before, int count); | |
} | |
/** | |
* @param editText | |
* @param formatType String formatting style like "%,.2f $" | |
*/ | |
public MoneyTextWatcher(EditText editText, String formatType) { | |
super("Informe um valor"); | |
init(editText, formatType, null); | |
} | |
public MoneyTextWatcher(EditText editText, String formatType, View linkedView) { | |
super("Informe um valor"); | |
init(editText, formatType, linkedView); | |
} | |
@Override | |
public void beforeTextChanged(CharSequence s, int start, int count, int after) { | |
FileLog.d("::beforeTextChanged:" + "CharSequence " + s + " start=" + start + " count=" + count + " " + "after=" + after); | |
isDeleting = after <= 0 && count > 0; | |
if (!s.toString().equals(current)) { | |
editText.removeTextChangedListener(this); | |
String clean_text = s.toString().replaceAll("[^\\d]", ""); | |
editText.setText(clean_text); | |
editText.addTextChangedListener(this); | |
} | |
if (delegate != null) delegate.beforeTextChanged(s, start, count, after); | |
} | |
@Override | |
public void onTextChanged(CharSequence s, int start, int before, int count) { | |
FileLog.d("::onTextChanged:" + "CharSequence " + s + " start=" + start + " count=" + count + " before=" + before); | |
if (start == 0 && before >= 4) { | |
insertingSelected = true; | |
} | |
if (delegate != null) delegate.onTextChanged(s, start, before, count); | |
} | |
@Override | |
public synchronized void afterTextChanged(Editable s) { | |
FileLog.d("::afterTextChanged:" + "Editable " + s + "; Current " + current); | |
if (!s.toString().equals(current)) { | |
editText.removeTextChangedListener(this); | |
String digits = s.toString(); | |
if (insertingSelected) { | |
digits = String.valueOf(toDouble(digits)); | |
} | |
String formatted_text; | |
double v_value = 0; | |
try { | |
formatted_text = String.format(new Locale("pt", "BR"), formatType, Double.parseDouble(digits)); | |
} catch (NumberFormatException nfe) { | |
v_value = toDouble(digits); | |
formatted_text = String.format(new Locale("pt", "BR"), formatType, v_value); | |
} | |
current = formatted_text; | |
editText.setText(formatted_text); | |
editText.setSelection(formatted_text.length()); | |
if (linkedText != null) { | |
if (linkedText instanceof TextView) { | |
((TextView) linkedText).setText(formatted_text); | |
} else if (linkedText instanceof TextDetailCell) { | |
((TextDetailCell) linkedText).setLeftText(formatted_text); | |
} | |
} | |
editText.addTextChangedListener(this); | |
} | |
if (delegate != null) delegate.afterTextChanged(s); | |
} | |
public int getMax_length() { | |
return max_length; | |
} | |
public void setMax_length(int max_length) { | |
this.max_length = max_length; | |
} | |
@Override | |
public boolean isValid(@NonNull CharSequence text, boolean isEmpty) { | |
return !isEmpty && toDouble(editText.getText().toString()) > 0; | |
} | |
@Override | |
public void onFocusChange(View v, boolean hasFocus) { | |
if (editText instanceof MaterialEditText) ((MaterialEditText) editText).setAutoValidate(true); | |
if (Utilities.toDouble(editText.getText().toString()) <= 0d) { | |
if (hasFocus) { | |
editText.setText("0"); | |
editText.setSelection(editText.length()); | |
} else { | |
editText.setText(""); | |
} | |
} | |
if (delegate != null) delegate.onFocusChange(v, hasFocus); | |
} | |
public void setDelegate(MoneyTextDelegate delegate) { | |
this.delegate = delegate; | |
} | |
/** | |
* @param str String with special caracters | |
* @return a double value of string | |
*/ | |
public double toDouble(String str) { | |
str = str.replaceAll("[^\\d]", ""); | |
if (str != null && str.length() > 0) { | |
double value = Double.parseDouble(str); | |
String s_value = Double.toString(Math.abs(value / 100)); | |
int integerPlaces = s_value.indexOf('.'); | |
if (integerPlaces > max_length) { | |
value = Double.parseDouble(deleteLastChar(str)); | |
} | |
return value / 100; | |
} else { | |
return 0; | |
} | |
} | |
private String deleteLastChar(String clean_text) { | |
if (clean_text.length() > 0) { | |
clean_text = clean_text.substring(0, clean_text.length() - 1); | |
} else { | |
clean_text = "0"; | |
} | |
return clean_text; | |
} | |
private void init(EditText editText, String formatType, View valorFinal) { | |
this.editText = editText; | |
this.formatType = formatType; | |
this.linkedText = valorFinal; | |
editText.setOnFocusChangeListener(this); | |
FileLog.e("::MoneyTextWatcher:" + "formatType " + formatType); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment