I want to separate automatically edit text like (9,99,999) like this. i searched for this on web but i am not getting proper solution for this.
can you please help me.thank you stack overflow.
You can use DecimalFormat for this like below Code:
public String formatNumber(double d) {
DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);
formatter.applyPattern("#,###");
return formatter.format(d);
}
You Can Pass Pattern as you want.
public static String formatCurrency(String number) {
try {
number = NumberFormat.getNumberInstance(Locale.US).format(Double.valueOf(number));
} catch (Exception e) {
}
return number;
}
This is what i did. Works perfectly
Try this.
public class NumberTextWatcherForThousand implements TextWatcher {
EditText editText;
public NumberTextWatcherForThousand(EditText editText) {
this.editText = editText;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
try
{
editText.removeTextChangedListener(this);
String value = editText.getText().toString();
if (value != null && !value.equals(""))
{
if(value.startsWith(".")){ //adds "0." when only "." is pressed on begining of writting
editText.setText("0.");
}
if(value.startsWith("0") && !value.startsWith("0.")){
editText.setText(""); //Prevents "0" while starting but not "0."
}
String str = editText.getText().toString().replaceAll(",", "");
if (!value.equals(""))
editText.setText(getDecimalFormat(str));
editText.setSelection(editText.getText().toString().length());
}
editText.addTextChangedListener(this);
return;
}
catch (Exception ex)
{
ex.printStackTrace();
editText.addTextChangedListener(this);
}
}
public static String getDecimalFormat(String value)
{
StringTokenizer lst = new StringTokenizer(value, ".");
String str1 = value;
String str2 = "";
if (lst.countTokens() > 1)
{
str1 = lst.nextToken();
str2 = lst.nextToken();
}
String str3 = "";
int i = 0;
int j = -1 + str1.length();
if (str1.charAt( -1 + str1.length()) == '.')
{
j--;
str3 = ".";
}
for (int k = j;; k--)
{
if (k < 0)
{
if (str2.length() > 0)
str3 = str3 + "." + str2;
return str3;
}
if (i == 3)
{
str3 = "," + str3;
i = 0;
}
str3 = str1.charAt(k) + str3;
i++;
}
}
//Trims all the comma of the string and returns
public static String trimCommaOfString(String string) {
if(string.contains(",")){
return string.replace(",","");}
else {
return string;
}
}
}
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
editText.removeTextChangedListener(this);
try {
StringBuilder originalString = new StringBuilder(editable.toString().replaceAll(",", ""));
int indx = 0;
for (int i = originalString.length(); i > 0; i--) {
if (indx % 3 == 0 && indx > 0)
originalString = originalString.insert(i, ",");
indx++;
}
editText.setText(originalString);
editText.setSelection(originalString.length());
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
editText.addTextChangedListener(this);
}
});
Related
I am using from bellow code for converting numbers to currency format when text changes but when I scrolled the recyclerView I lost true data. What can I do :
public class ManagePriceProductsAdapter extends RecyclerView.Adapter<ManagePriceProductsAdapter.ViewHolder> {
private List<ManagePriceProductsModel.DataValue> managePriceProductsModelList;
private Context context;
private getListDiscountInterface getListDiscountInterface;
private int vendorId = -1;
public ManagePriceProductsAdapter(Context context,
List<ManagePriceProductsModel.DataValue> managePriceProductsModelList,
getListDiscountInterface getListDiscountInterface,
int vendorId) {
this.context = context;
this.managePriceProductsModelList = managePriceProductsModelList;
this.getListDiscountInterface = getListDiscountInterface;
this.vendorId = vendorId;
}
#Override
public ManagePriceProductsAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context)
.inflate(R.layout.list_item_manage_price_products, viewGroup, false);
return new ManagePriceProductsAdapter.ViewHolder(view,
new DiscountNumberTextWatcherWithSeperator(),
new OriginalNumberTextWatcherWithSeperator());
}
public void getListDiscount() {
getListDiscountInterface.sendGetListDiscountToActivity(managePriceProductsModelList);
}
public void backButton() {
getListDiscountInterface.backButtonForListDiscount(managePriceProductsModelList);
}
public void resetAdapter() {
this.managePriceProductsModelList.clear();
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(final ManagePriceProductsAdapter.ViewHolder viewHolder, int position) {
viewHolder.discountNumberTextWatcherWithSeperator.updatePosition(viewHolder.getAdapterPosition(),
viewHolder.discountPriceEdittext,
viewHolder.originalPriceEdittext);
viewHolder.originalNumberTextWatcherWithSeperator.updatePosition(viewHolder.getAdapterPosition(),
viewHolder.originalPriceEdittext);
try {
if (managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getTitle() != null) {
if (!TextUtils.isEmpty(managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getTitle().trim())) {
String productName = managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getTitle().trim();
viewHolder.titleTextview.setText(productName);
} else {
viewHolder.titleTextview.setText("----");
}
} else {
viewHolder.titleTextview.setText("----");
}
} catch (Exception ex) {
if (vendorId != -1) {
Throwable t = new Throwable(ex + ", vendorId: " + vendorId).fillInStackTrace();
FirebaseCrash.report(t);
} else {
Throwable t = new Throwable(ex + ", vendorId: empty").fillInStackTrace();
FirebaseCrash.report(t);
}
}
try {
if (managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getPrice() != null) {
Long productPrice = managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getPrice();
if (productPrice != null && productPrice != 0 && productPrice > 0) {
viewHolder.originalPriceEdittext.setText(String.valueOf(productPrice));
} else {
viewHolder.originalPriceEdittext.setText("");
}
}
} catch (Exception ex) {
if (vendorId != -1) {
Throwable t = new Throwable(ex + ", vendorId: " + vendorId).fillInStackTrace();
FirebaseCrash.report(t);
} else {
Throwable t = new Throwable(ex + ", vendorId: empty").fillInStackTrace();
FirebaseCrash.report(t);
}
}
try {
if (managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getDiscountedPrice() != null) {
Long discountPrice = managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getDiscountedPrice();
if (discountPrice != null && discountPrice != 0 && discountPrice > 0) {
viewHolder.discountPriceEdittext.setText(String.valueOf(discountPrice));
} else {
viewHolder.discountPriceEdittext.setText("");
}
}
} catch (Exception ex) {
if (vendorId != -1) {
Throwable t = new Throwable(ex + ", vendorId: " + vendorId).fillInStackTrace();
FirebaseCrash.report(t);
} else {
Throwable t = new Throwable(ex + ", vendorId: empty").fillInStackTrace();
FirebaseCrash.report(t);
}
}
}
#Override
public int getItemCount() {
return managePriceProductsModelList.size();
}
public interface getListDiscountInterface {
void sendGetListDiscountToActivity(List<ManagePriceProductsModel.DataValue> managePriceProductsModelList);
void backButtonForListDiscount(List<ManagePriceProductsModel.DataValue> managePriceProductsModelList);
}
class ViewHolder extends RecyclerView.ViewHolder {
//region ViewBinding
#BindView(R.id.title_textview)
TextView titleTextview;
#BindView(R.id.original_price_edittext)
EditText originalPriceEdittext;
#BindView(R.id.discount_price_edittext)
EditText discountPriceEdittext;
DiscountNumberTextWatcherWithSeperator discountNumberTextWatcherWithSeperator;
OriginalNumberTextWatcherWithSeperator originalNumberTextWatcherWithSeperator;
//endregion
ViewHolder(View view,
DiscountNumberTextWatcherWithSeperator discountNumberTextWatcherWithSeperator,
OriginalNumberTextWatcherWithSeperator originalNumberTextWatcherWithSeperator) {
super(view);
ButterKnife.bind(this, itemView);
this.discountNumberTextWatcherWithSeperator = discountNumberTextWatcherWithSeperator;
this.discountPriceEdittext.addTextChangedListener(discountNumberTextWatcherWithSeperator);
this.originalNumberTextWatcherWithSeperator = originalNumberTextWatcherWithSeperator;
this.originalPriceEdittext.addTextChangedListener(originalNumberTextWatcherWithSeperator);
}
}
private class DiscountNumberTextWatcherWithSeperator implements TextWatcher {
private EditText discountEditText;
private EditText originalEditText;
private int position;
private String getDecimalFormattedString(String value) {
StringTokenizer lst = new StringTokenizer(value, ".");
String str1 = value;
String str2 = "";
if (lst.countTokens() > 1) {
str1 = lst.nextToken();
str2 = lst.nextToken();
}
String str3 = "";
int i = 0;
int j = -1 + str1.length();
if (str1.charAt(-1 + str1.length()) == '.') {
j--;
str3 = ".";
}
for (int k = j; ; k--) {
if (k < 0) {
if (str2.length() > 0)
str3 = str3 + "." + str2;
return str3;
}
if (i == 3) {
str3 = "," + str3;
i = 0;
}
str3 = str1.charAt(k) + str3;
i++;
}
}
public void updatePosition(int position,
EditText discountEditText,
EditText originalEditText) {
this.position = position;
this.discountEditText = discountEditText;
this.originalEditText = originalEditText;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (charSequence.length() > 0) {
originalEditText.setPaintFlags(originalEditText.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
dataValue.setId(managePriceProductsModelList.get(position).getId());
dataValue.setPrice(managePriceProductsModelList.get(position).getPrice());
dataValue.setDiscountedPrice(Long.parseLong(charSequence.toString().replace(",", "")));
managePriceProductsModelList.set(position, dataValue);
} else if (charSequence.length() == 0) {
originalEditText.setPaintFlags(originalEditText.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
dataValue.setId(managePriceProductsModelList.get(position).getId());
dataValue.setPrice(managePriceProductsModelList.get(position).getPrice());
dataValue.setDiscountedPrice(null);
managePriceProductsModelList.set(position, dataValue);
}
}
#Override
public void afterTextChanged(Editable editable) {
try {
discountEditText.removeTextChangedListener(this);
String value = discountEditText.getText().toString();
if (!value.equals("")) {
if (value.startsWith(".")) {
discountEditText.setText("0.");
}
if (value.startsWith("0") && !value.startsWith("0.")) {
discountEditText.setText("");
}
String str = discountEditText.getText().toString().replaceAll(",", "");
if (!value.equals(""))
discountEditText.setText(getDecimalFormattedString(str));
discountEditText.setSelection(discountEditText.getText().toString().length());
}
discountEditText.addTextChangedListener(this);
} catch (Exception ex) {
ex.printStackTrace();
discountEditText.addTextChangedListener(this);
}
}
}
private class OriginalNumberTextWatcherWithSeperator implements TextWatcher {
private EditText editText;
private int position;
private String getDecimalFormattedString(String value) {
StringTokenizer lst = new StringTokenizer(value, ".");
String str1 = value;
String str2 = "";
if (lst.countTokens() > 1) {
str1 = lst.nextToken();
str2 = lst.nextToken();
}
String str3 = "";
int i = 0;
int j = -1 + str1.length();
if (str1.charAt(-1 + str1.length()) == '.') {
j--;
str3 = ".";
}
for (int k = j; ; k--) {
if (k < 0) {
if (str2.length() > 0)
str3 = str3 + "." + str2;
return str3;
}
if (i == 3) {
str3 = "," + str3;
i = 0;
}
str3 = str1.charAt(k) + str3;
i++;
}
}
public void updatePosition(int position,
EditText editText) {
this.position = position;
this.editText = editText;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (charSequence.length() > 0) {
ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
dataValue.setId(managePriceProductsModelList.get(position).getId());
dataValue.setPrice(Long.parseLong(charSequence.toString().replace(",", "")));
dataValue.setDiscountedPrice(managePriceProductsModelList.get(position).getDiscountedPrice());
managePriceProductsModelList.set(position, dataValue);
} else if (charSequence.length() == 0) {
ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
dataValue.setId(managePriceProductsModelList.get(position).getId());
dataValue.setPrice(null);
dataValue.setDiscountedPrice(managePriceProductsModelList.get(position).getDiscountedPrice());
managePriceProductsModelList.set(position, dataValue);
}
}
#Override
public void afterTextChanged(Editable editable) {
try {
editText.removeTextChangedListener(this);
String value = editText.getText().toString();
if (!value.equals("")) {
if (value.startsWith(".")) {
editText.setText("0.");
}
if (value.startsWith("0") && !value.startsWith("0.")) {
editText.setText("");
}
String str = editText.getText().toString().replaceAll(",", "");
if (!value.equals(""))
editText.setText(getDecimalFormattedString(str));
editText.setSelection(editText.getText().toString().length());
}
editText.addTextChangedListener(this);
} catch (Exception ex) {
ex.printStackTrace();
editText.addTextChangedListener(this);
}
}
}
}
As the comments above it is not recommended to use edittext in recyclerview.
If you have to do this can you try to use
viewHolder.setIsRecyclable(false);
in your onBindViewHolder method
You can use this library to support this
Create a ViewState
new ViewState<>() {
private String savedValue; /* here will be saved a value for each item by createViewStateID() */
#Override
public void clear(#NonNull final ViewHolder<ViewFinder> holder) {
holder.getViewFinder().setText(R.id.text, "");
}
#Override
public void save(#NonNull final ViewHolder<ViewFinder> holder) {
savedValue = holder.getViewFinder().<EditText>find(R.id.text).getText().toString();
}
#Override
public void restore(#NonNull final ViewHolder<ViewFinder> holder) {
holder.getViewFinder().setText(R.id.text, savedValue);
}
};
Set that ViewState to your ViewRenderer
adapter.registerRenderer(new ViewRenderer<>(
R.layout.your_item_layout, //your layout
YourItemModel.class, //your model
(model, finder, payloads) -> finder.setText(R.id.text, model.getValue()), //your binding
getYourViewStateProvider() // here is your ViewState
));
More info you can find here
You can use the code below to keep hold of your dynamic values.
Paste this code inside your adapter. This allows to assign a unique id to your items. Just make sure the id assigned to all the items in the recyclerview must be unique.
override fun getItemViewType(position: Int) = position
override fun getItemId(position: Int) = position.toLong()
I am using RxTextView.textChanges for EditText that when the user is typing change value of EditText to convert numbers to currency format like below:
1,000
But I can't see any convert numbers to currency format.
I am using from: NumberFormat.getNumberInstance(Locale.US).format(productPrice);
My code is like bellow:
Observable<CharSequence> observableDiscountPrice = RxTextView.textChanges(discountPriceEdittext);
observableDiscountPrice.map(new Function<CharSequence, Boolean>() {
#Override
public Boolean apply(#io.reactivex.annotations.NonNull CharSequence charSequence) throws Exception {
try {
if (charSequence.length() > 0) {
String pPrice = NumberFormat.getNumberInstance(Locale.US).format(charSequence.toString());
originalPriceEdittext.setText(String.valueOf(pPrice));
return true;
} else {
return false;
}
} catch (Exception e) {
return true;
}
}
}).subscribe(new Subject<Boolean>() {
#Override
public boolean hasObservers() {
return false;
}
#Override
public boolean hasThrowable() {
return false;
}
#Override
public boolean hasComplete() {
return false;
}
#Override
public Throwable getThrowable() {
return null;
}
#Override
protected void subscribeActual(Observer<? super Boolean> observer) {
}
#Override
public void onSubscribe(#io.reactivex.annotations.NonNull Disposable d) {
}
#Override
public void onNext(#io.reactivex.annotations.NonNull Boolean aBoolean) {
}
#Override
public void onError(#io.reactivex.annotations.NonNull Throwable e) {
}
#Override
public void onComplete() {
}
});
Use this TextWatcher class:
public class NumberTextWatcherWithSeperator implements TextWatcher {
private EditText editText;
public NumberTextWatcherWithSeperator(EditText editText) {
this.editText = editText;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
try {
editText.removeTextChangedListener(this);
String value = editText.getText().toString();
if (!value.equals("")) {
if (value.startsWith(".")) {
editText.setText("0.");
}
if (value.startsWith("0") && !value.startsWith("0.")) {
editText.setText("");
}
String str = editText.getText().toString().replaceAll(",", "");
if (!value.equals(""))
editText.setText(getDecimalFormattedString(str));
editText.setSelection(editText.getText().toString().length());
}
editText.addTextChangedListener(this);
} catch (Exception ex) {
ex.printStackTrace();
editText.addTextChangedListener(this);
}
}
private static String getDecimalFormattedString(String value) {
StringTokenizer lst = new StringTokenizer(value, ".");
String str1 = value;
String str2 = "";
if (lst.countTokens() > 1) {
str1 = lst.nextToken();
str2 = lst.nextToken();
}
String str3 = "";
int i = 0;
int j = -1 + str1.length();
if (str1.charAt(-1 + str1.length()) == '.') {
j--;
str3 = ".";
}
for (int k = j; ; k--) {
if (k < 0) {
if (str2.length() > 0)
str3 = str3 + "." + str2;
return str3;
}
if (i == 3) {
str3 = "," + str3;
i = 0;
}
str3 = str1.charAt(k) + str3;
i++;
}
}
}
and
yourEditText.addTextChangedListener(new NumberTextWatcherWithSeperator(yourEditText));
Take a look at https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
DecimalFormat myFormatter = new DecimalFormat("###,###.###");
String output = myFormatter.format(156456.673);
System.out.println(156456.673 + " " + "###,###.###" + " " + output);
// I/System.out: 156456.673 ###,###.### 156,456.673
I'm using this watcher to do the same thing:
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
public class CurrencyTextWatcher implements TextWatcher {
private EditText ed;
private String lastText;
private boolean bDel = false;
private boolean bInsert = false;
private int pos;
public CurrencyTextWatcher(EditText ed) {
this.ed = ed;
}
public static String getStringWithSeparator(long value) {
DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
String f = formatter.format(value);
return f;
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
bDel = false;
bInsert = false;
if (before == 1 && count == 0) {
bDel = true;
pos = start;
} else if (before == 0 && count == 1) {
bInsert = true;
pos = start;
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
lastText = s.toString();
}
#Override
public void afterTextChanged(Editable s) {
ed.removeTextChangedListener(this);
StringBuilder sb = new StringBuilder();
String text = s.toString();
for (int i = 0; i < text.length(); i++) {
if ((text.charAt(i) >= 0x30 && text.charAt(i) <= 0x39) || text.charAt(i) == '.' || text.charAt(i) == ',')
sb.append(text.charAt(i));
}
if (!sb.toString().equals(s.toString())) {
bDel = bInsert = false;
}
String newText = getFormattedString(sb.toString());
s.clear();
s.append(newText);
ed.addTextChangedListener(this);
if (bDel) {
int idx = pos;
if (lastText.length() - 1 > newText.length())
idx--;
if (idx < 0)
idx = 0;
ed.setSelection(idx);
} else if (bInsert) {
int idx = pos + 1;
if (lastText.length() + 1 < newText.length())
idx++;
if (idx > newText.length())
idx = newText.length();
ed.setSelection(idx);
}
}
private String getFormattedString(String text) {
String res = "";
try {
String temp = text.replace(",", "");
long part1;
String part2 = "";
int dotIndex = temp.indexOf(".");
if (dotIndex >= 0) {
part1 = Long.parseLong(temp.substring(0, dotIndex));
if (dotIndex + 1 <= temp.length()) {
part2 = temp.substring(dotIndex + 1).trim().replace(".", "").replace(",", "");
}
} else
part1 = Long.parseLong(temp);
res = getStringWithSeparator(part1);
if (part2.length() > 0)
res += "." + part2;
else if (dotIndex >= 0)
res += ".";
} catch (Exception ex) {
ex.printStackTrace();
}
return res;
}
}
In case you want to and a dollar sign
fun multiply_two_numbers() {
val x = etValOne.text.toString()
val y = etValTwo.text.toString()
val c = x.toDouble().times(y.toDouble())
//val c = (x.toDouble() * y.toDouble())
val df = DecimalFormat("$ "+"0.00")
df.roundingMode = RoundingMode.CEILING
df.format(c)
etANS.setText(df.format(c))
}
Can I ask how to format string value e.g. 5000000.00 to 5,000,000.00? Apparently I'm doing currency related stuff for android application, I can managed to just format string value 5000000 to 5,000,000 without the dot separator in the edit text. I would like to store the string value for later to be used to parseDouble so that I will need to calculate and have some decimals. I managed to do with just comma separator but any idea on how to make the dot to be shown in the edit text as well?
The following is my code:
amountText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
amountText.removeTextChangedListener(this);
if(!amountText.getText().toString().equals(""))
{
try {
String editText = amountText.getText().toString();
String newStr = editText.replace("$", "").replace(",", "");
customer.getProperty().get(groupPosition).setAmount(newStr);
String formattedString = formatString(customer.getProperty().get(groupPosition).getAmount());
amountText.setText(formattedString);
amountText.setSelection(amountText.getText().length());
// to place the cursor at the end of text
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
amountText.addTextChangedListener(this);
}
});
public String formatString(String s)
{
String givenstring = s.toString();
Long longval;
if (givenstring.contains(",")) {
givenstring = givenstring.replaceAll(",", "");
}
longval = Long.parseLong(givenstring);
DecimalFormat formatter = new DecimalFormat("#,###,###");
String formattedString = formatter.format(longval);
return formattedString;
}
I have tested use parseDouble but when I input "." in EditText, it just won't appear, and if I used long variable instead, it will give wrong format and error. (java.lang.NumberFormatException: Invalid long: "500000.00"). All values are done in string and later processing I will just parse the value when doing calculation.
Thank you and appreciate for anyone guidance and I apologize if there exists the post that is similar as I did not manage to find solution yet.
This is working & fully tested code just copy & paste it to try
TextWatcher amountTextWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
int cursorPosition = etAmount.getSelectionEnd();
String originalStr = etAmount.getText().toString();
//To restrict only two digits after decimal place
etAmount.setFilters(new InputFilter[]{new MoneyValueFilter(Integer.parseInt(2))});
try {
etAmount.removeTextChangedListener(this);
String value = etAmount.getText().toString();
if (value != null && !value.equals("")) {
if (value.startsWith(".")) {
etAmount.setText("0.");
}
if (value.startsWith("0") && !value.startsWith("0.")) {
etAmount.setText("");
}
String str = etAmount.getText().toString().replaceAll(",", "");
if (!value.equals(""))
etAmount.setText(getDecimalFormattedString(str));
int diff = etAmount.getText().toString().length() - originalStr.length();
etAmount.setSelection(cursorPosition + diff);
}
etAmount.addTextChangedListener(this);
} catch (Exception ex) {
ex.printStackTrace();
etAmount.addTextChangedListener(this);
}
}
}
};
etAmount.addTextChangedListener(amountTextWatcher);
Here is method to add comma seperator to decimal number
/**
* Get decimal formated string to include comma seperator to decimal number
*
* #param value
* #return
*/
public static String getDecimalFormattedString(String value) {
if (value != null && !value.equalsIgnoreCase("")) {
StringTokenizer lst = new StringTokenizer(value, ".");
String str1 = value;
String str2 = "";
if (lst.countTokens() > 1) {
str1 = lst.nextToken();
str2 = lst.nextToken();
}
String str3 = "";
int i = 0;
int j = -1 + str1.length();
if (str1.charAt(-1 + str1.length()) == '.') {
j--;
str3 = ".";
}
for (int k = j; ; k--) {
if (k < 0) {
if (str2.length() > 0)
str3 = str3 + "." + str2;
return str3;
}
if (i == 3) {
str3 = "," + str3;
i = 0;
}
str3 = str1.charAt(k) + str3;
i++;
}
}
return "";
}
Method to restrict only two digits after decimal place in edittext
/**
* Restrict digits after decimal point value as per currency
*/
class MoneyValueFilter extends DigitsKeyListener {
private int digits;
public MoneyValueFilter(int i) {
super(false, true);
digits = i;
}
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
CharSequence out = super.filter(source, start, end, dest, dstart, dend);
// if changed, replace the source
if (out != null) {
source = out;
start = 0;
end = out.length();
}
int len = end - start;
// if deleting, source is empty
// and deleting can't break anything
if (len == 0) {
return source;
}
int dlen = dest.length();
// Find the position of the decimal .
for (int i = 0; i < dstart; i++) {
if (dest.charAt(i) == '.') {
// being here means, that a number has
// been inserted after the dot
// check if the amount of digits is right
return getDecimalFormattedString((dlen - (i + 1) + len > digits) ? "" : String.valueOf(new SpannableStringBuilder(source, start, end)));
}
}
for (int i = start; i < end; ++i) {
if (source.charAt(i) == '.') {
// being here means, dot has been inserted
// check if the amount of digits is right
if ((dlen - dend) + (end - (i + 1)) > digits)
return "";
else
break; // return new SpannableStringBuilder(source,
// start, end);
}
}
// if the dot is after the inserted part,
// nothing can break
return getDecimalFormattedString(String.valueOf(new SpannableStringBuilder(source, start, end)));
}
}
Try this:
public void afterTextChanged(Editable view) {
String s = null;
try {
// The comma in the format specifier does the trick
s = String.format("%,d", Long.parseLong(view.toString()));
} catch (NumberFormatException e) {
}
// Set s back to the view after temporarily removing the text change listener
}
Source: How to Automatically add thousand separators as number is input in EditText
I want to separate automatically edit text like (9,99,999) like this. I searched for this on the web but I have not found a proper solution for this.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText editText = (EditText) findViewById(R.id.edittext);
editText.addTextChangedListener(new NumberTextWatcherForThousand(editText)); NumberTextWatcherForThousand.trimCommaOfString(editText.getText().toString());
}
}
NumberTextWatcherForThousand
public class NumberTextWatcherForThousand implements TextWatcher {
EditText editText;
public NumberTextWatcherForThousand(EditText editText) {
this.editText = editText;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
try
{
editText.removeTextChangedListener(this);
String value = editText.getText().toString();
if (value != null && !value.equals(""))
{
if(value.startsWith(".")){
editText.setText("0.");
}
if(value.startsWith("0") && !value.startsWith("0.")){
editText.setText("");
}
String str = editText.getText().toString().replaceAll(",", "");
if (!value.equals(""))
editText.setText(getDecimalFormattedString(str));
editText.setSelection(editText.getText().toString().length());
}
editText.addTextChangedListener(this);
return;
}
catch (Exception ex)
{
ex.printStackTrace();
editText.addTextChangedListener(this);
}
}
public static String getDecimalFormattedString(String value)
{
StringTokenizer lst = new StringTokenizer(value, ".");
String str1 = value;
String str2 = "";
if (lst.countTokens() > 1)
{
str1 = lst.nextToken();
str2 = lst.nextToken();
}
String str3 = "";
int i = 0;
int j = -1 + str1.length();
if (str1.charAt( -1 + str1.length()) == '.')
{
j--;
str3 = ".";
}
for (int k = j;; k--)
{
if (k < 0)
{
if (str2.length() > 0)
str3 = str3 + "." + str2;
return str3;
}
if (i == 3)
{
str3 = "," + str3;
i = 0;
}
str3 = str1.charAt(k) + str3;
i++;
}
}
public static String trimCommaOfString(String string) {
if(string.contains(",")){
return string.replace(",","");}
else {
return string;
}
}
}
This will format the text and add commas in thousands place inside your edit text.
#Override
public void afterTextChanged(Editable editable) {
try {
// The comma in the format specifier does the trick
editText.setText(String.format("%,d", Long.parseLong(editable.toString())));
} catch (NumberFormatException e) {
}
}
try this below code :-
import java.text.DecimalFormat;
import java.text.ParseException;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
public class NumberTextWatcher implements TextWatcher {
private DecimalFormat df;
private DecimalFormat dfnd;
private boolean hasFractionalPart;
private EditText et;
public NumberTextWatcher(EditText et)
{
df = new DecimalFormat("#,###.##");
df.setDecimalSeparatorAlwaysShown(true);
dfnd = new DecimalFormat("#,###");
this.et = et;
hasFractionalPart = false;
}
#SuppressWarnings("unused")
private static final String TAG = "NumberTextWatcher";
#Override
public void afterTextChanged(Editable s)
{
et.removeTextChangedListener(this);
try {
int inilen, endlen;
inilen = et.getText().length();
String v = s.toString().replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "");
Number n = df.parse(v);
int cp = et.getSelectionStart();
if (hasFractionalPart) {
et.setText(df.format(n));
} else {
et.setText(dfnd.format(n));
}
endlen = et.getText().length();
int sel = (cp + (endlen - inilen));
if (sel > 0 && sel <= et.getText().length()) {
et.setSelection(sel);
} else {
// place cursor at the end?
et.setSelection(et.getText().length() - 1);
}
} catch (NumberFormatException nfe) {
// do nothing?
} catch (ParseException e) {
// do nothing?
}
et.addTextChangedListener(this);
}
#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().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator())))
{
hasFractionalPart = true;
} else {
hasFractionalPart = false;
}
}
}
and in your edittext
editText.addTextChangedListener(new NumberTextWatcher(editText));
In build.gradle add following lines
repositories{
maven { url "https://jitpack.io" }
}
dependencies {
compile 'com.github.BlacKCaT27:CurrencyEditText:v1.4.4'
}
Instead of EditText use following Code
<com.blackcat.currencyedittext.CurrencyEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
check this link https://github.com/BlacKCaT27/CurrencyEditText
I am writing a Convertor Application and I want a thousand separator automatically added to the digits in realtime, so after I implemented this applypattern code on the TextWatcher, now I can not make floationg point inputs.....here is my code for the Editext
am2 = new TextWatcher()
{
boolean isEdiging;
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
public void afterTextChanged(Editable s) {
if (s.toString().equals("")) {
amount.setText("");
value = 0;
}else{
if(isEdiging) return;
isEdiging = true;
StringBuffer strBuff = new StringBuffer();
char c;
for (int i = 0; i < amount2.getText().toString().length() ; i++) {
c = amount2.getText().toString().charAt(i);
if (Character.isDigit(c)) {
strBuff.append(c);
}
}
value = Double.parseDouble(strBuff.toString());
reverse();
NumberFormat nf2 = NumberFormat.getInstance(Locale.ENGLISH);
((DecimalFormat)nf2).applyPattern("###,###.#######");
s.replace(0, s.length(), nf2.format(value));
isEdiging = false;
}
}
};
So is there any way of inputting floating point within the EditText?
This class solves the problem
public class NumberTextWatcher implements TextWatcher {
private DecimalFormat df;
private DecimalFormat dfnd;
private boolean hasFractionalPart;
private EditText et;
public NumberTextWatcher(EditText et)
{
df = new DecimalFormat("#,###.##");
df.setDecimalSeparatorAlwaysShown(true);
dfnd = new DecimalFormat("#,###");
this.et = et;
hasFractionalPart = false;
}
#SuppressWarnings("unused")
private static final String TAG = "NumberTextWatcher";
public void afterTextChanged(Editable s)
{
et.removeTextChangedListener(this);
try {
int inilen, endlen;
inilen = et.getText().length();
String v = s.toString().replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "");
Number n = df.parse(v);
int cp = et.getSelectionStart();
if (hasFractionalPart) {
et.setText(df.format(n));
} else {
et.setText(dfnd.format(n));
}
endlen = et.getText().length();
int sel = (cp + (endlen - inilen));
if (sel > 0 && sel <= et.getText().length()) {
et.setSelection(sel);
} else {
// place cursor at the end?
et.setSelection(et.getText().length() - 1);
}
} catch (NumberFormatException nfe) {
// do nothing?
} catch (ParseException e) {
// do nothing?
}
et.addTextChangedListener(this);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
public void onTextChanged(CharSequence s, int start, int before, int count)
{
if (s.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator())))
{
hasFractionalPart = true;
} else {
hasFractionalPart = false;
}
}
}