I have search a lot but not found solution to my problem.
How can I have a editText in which user can enter number in decimal format in which format should be a integer before decimal and two integer after decimal.
If user enter 1 then it should be 1.00 and not allow to enter value grater then 9.99.
I have refer different code but nothing is working.
below is my code -
public class DecimalDigitsInputFilter implements InputFilter {
Pattern mPattern;
public DecimalDigitsInputFilter(int digitsBeforeZero,int digitsAfterZero) {
mPattern=Pattern.compile("[0-9]{0," + (digitsBeforeZero-1) + "}+((\\.[0-9]{0," + (digitsAfterZero-1) + "})?)||(\\.)?");
}
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
Matcher matcher=mPattern.matcher(dest);
if(!matcher.matches())
return "";
return null;
}
}
and
mSetupProfileViewHolder.mAthleteGPAET.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(3,2)});
but it allow user to input value all inter like 333,999 etc.
You want to use a TextWatcher and then check what the user has typed before they submit it. Here is an example of the code you want to implement:
final EditText et = (EditText) findViewById(R.id.editText);
et.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence arg0, int arg1, int arg2,int arg3) {
}
public void beforeTextChanged(CharSequence arg0, int arg1,int arg2, int arg3) {
}
public void afterTextChanged(Editable arg0) {
if (arg0.length() > 0) {
String str = et.getText().toString();
et.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL) {
count--;
InputFilter[] fArray = new InputFilter[1];
fArray[0] = new InputFilter.LengthFilter(100);
et.setFilters(fArray);
//change the edittext's maximum length to 100.
//If we didn't change this the edittext's maximum length will
//be number of digits we previously entered.
}
return false;
}
});
char t = str.charAt(arg0.length() - 1);
if (t == '.') {
count = 0;
}
if (count >= 0) {
if (count == 2) {
InputFilter[] fArray = new InputFilter[1];
fArray[0] = new InputFilter.LengthFilter(arg0.length());
et.setFilters(fArray);
//prevent the edittext from accessing digits
//by setting maximum length as total number of digits we typed till now.
}
count++;
}
}
}
});
The above code will not allow the user to enter more than two digits after the decimal point and you can also enter any number of digits before the decimal point. Hope this helps, let me know if you have any issues!
Related
How can I set the fractional point after two integers in android and set the limit to 55 digits only? After searching a lot I am posting my problem here. I have an Edittext with an android:inputType="number" . I am able to set max limit to the EditText to 55 digits. I want user can able to type fractional digit also between 0 to 55 digits like 24.22 or 52.88.
Can some please tell me how can I achieve this?
Here is my code.
public class FuelCostCalculator extends DialogFragment {
EditText etLocation, etKilo, etLiter, etFuelCost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.fullscreen_dialog);
}
private void init(View view) {
//this is my editText
etLiter = view.findViewById(R.id.etLiter);
InputFilterMinMax filter = new InputFilterMinMax("0", "5499") {};
etLiter.setFilters(new InputFilter[]{filter});
}
}
My Filter class is :
public class InputFilterMinMax implements InputFilter {
private int min, max;
public InputFilterMinMax(int min, int max) {
this.min = min;
this.max = max;
}
public InputFilterMinMax(String min, String max) {
this.min = Integer.parseInt(min);
this.max = Integer.parseInt(max);
}
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (isInRange(min, max, input))
return null;
} catch (NumberFormatException nfe) { }
return "";
}
private boolean isInRange(int a, int b, int c) {
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
}
Any kind of help is appreciated :
Check this answer . Though it is not so much clean but it will work as per your needs. Assuming that actAddItemFromDropdownList is your edit text and you have set maximum digits limit in your Xml.
int max =0;
String text ="";
actAddItemFromDropdownList.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) {
if(actAddItemFromDropdownList.getText().length()>0){
if(text.equals(actAddItemFromDropdownList.getText().toString())){
text = "";
}else {
text = actAddItemFromDropdownList.getText().toString();
max = max + 1;
if (max == 2) {
text = text + ".";
max = 0;
actAddItemFromDropdownList.setText(text);
actAddItemFromDropdownList.setSelection(actAddItemFromDropdownList.getText().length());
}
}
}
}
});
try it and if it works mark as selected answer.
I want to format the input which is in the form of number in EditText.The format is 01-133134-124. I wanted first - after 2 number then next dash after 6 numbers.I tried but whenever I pressed delete/backspace because of the wrong entry the format stopped working and no dash is placed after input of 2 number or 6 numbers.Here is the code.Where Enrollement is the EditText field.
Format : 2digitnumber-6dignumber-3dignumber
Enrollement.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Enrollement.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL)
keyDel = 1;
return false;
}
});
if (keyDel == 0) {
int len = Enrollement.getText().length();
if (len == 2) {
int leng = Enrollement.getText().length();
if(leng==2) {
Enrollement.setText(Enrollement.getText() + "-");
Enrollement.setSelection(Enrollement.getText().length());
}
} else if (len == 9) {
int leng = Enrollement.getText().length();
if(leng==9) {
Enrollement.setText(Enrollement.getText() + "-");
Enrollement.setSelection(Enrollement.getText().length());
}
}
} else {
keyDel = 0;
}
}
#Override
public void afterTextChanged(Editable arg0) {
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
});
It would be much easier if you changed your approach a bit. You could be always analyzing unformatted verion of your string after every single change in your EditText.
Try this (remember to set android:maxLength="13" for your EditText):
Enrollement.addTextChangedListener(new TextWatcher() {
final int[] blockLengths = new int[]{2, 6, 3};
String mUnformatted = "";
#Override
public void onTextChanged (CharSequence s,int start, int before, int count){
String unformattedSeq = s.toString().replace("-", "");
if (mUnformatted.length() == unformattedSeq.length()) {
return; //length of text has not changed
}
mUnformatted = unformattedSeq;
//formatting sequence
StringBuilder formatted = new StringBuilder();
int blockIndex = 0;
int currentBlock = 0;
for (int i = 0; i < mUnformatted.length(); ++i) {
if (currentBlock == blockLengths[blockIndex]) {
formatted.append("-");
currentBlock = 0;
blockIndex++;
}
formatted.append(mUnformatted.charAt(i));
currentBlock++;
}
Enrollement.setText(formatted.toString());
Enrollement.setSelection(formatted.length());
}
#Override
public void beforeTextChanged (CharSequence s,int start, int count, int after){
}
#Override
public void afterTextChanged (Editable s){
}
});
This code should work correctly. You could only improve the setSelection part (currently if you delete a number in the middle of your EditText it will move your cursor to the end of the text).
In your onTextChanged method you could do:
String str = YourEditText.getText().toString();
if((str.length()==2 && len <str.length()) || (str.length()==6 && len <str.length())){
YourEditText.append("-"); }
Also,
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
String str = YourEditText.getText().toString();
len = str.length();
}
Adapted from this article.
I have an edittext, and a textwatcher that watches if SPACE arrived or not. If its a SPACE I would like to delete that instantly. Or if its a space I want to make sure it doesnt appear but indicate somehow (seterror, toast) for the user that space is not allowed.
edittext.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
//---//
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
I cannot define onkeydown in the afterTextChaned method, since it gives me an error.
public boolean onKeyDown(int keyCode, KeyEvent event) {
super.onKeyDown(keyCode, event);
if (keyCode == KeyEvent.KEYCODE_SPACE) {
}
}
So it is not working (syntax error, misplaced construct for the int keyCode.
Thanks you in advance!
The solution is as usually much simpler:
#Override
public void afterTextChanged(Editable s) {
String result = s.toString().replaceAll(" ", "");
if (!s.toString().equals(result)) {
ed.setText(result);
ed.setSelection(result.length());
// alert the user
}
}
This shouldn't have the problems of the previous attempts.
setSelection is there to set the cursor again at the end of your EditText:
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2,
int arg3) {}
#Override
public void beforeTextChanged(CharSequence s, int arg1, int arg2,
int arg3) {}
#Override
public void afterTextChanged(Editable arg0) {
if(editText.getText().toString().contains(" ")){ editText.setText(editText.getText().toString().replaceAll(" " , ""));
editText.setSelection(editText.getText().length());
Toast.makeText(getApplicationContext(), "No Spaces Allowed", Toast.LENGTH_LONG).show();
}
}});
boolean editclicked =false ;
edittext.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
editclicked = false ;
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {
editclicked = true;
});
Put this as a separate function:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (editclicked) {
if (keyCode == KeyEvent.KEYCODE_SPACE) {
return false
}
} else {
super.onKeyDown(keyCode, event);
}
}
#Override
public void afterTextChanged(Editable s) {
String result = s.toString().replaceAll("\\s", "");
if (!s.toString().equals(result)) {
int pos = editText.getSelectionStart() - (s.length() - result.length());
editText.setText(result);
editText.setSelection(Math.max(0,Math.min(pos, result.length())));
editText.setError("No spaces allowed");
}
}
\s matches any whitespace character (equal to [\r\n\t\f\v ])
Setting selection like this, allow you to enter or paste text in middle of edittext without loosing cursor position
My relatively simple solution for instant whitespace deletion without removing spannables (styles) in EditText:
Remove at start:
#Override
public void afterTextChanged(Editable s) {
int i;
for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
s.replace(0, i, "");
}
Basically that's it, but you can also do:
Remove at start (without interrupting first input):
#Override
public void afterTextChanged(Editable s) {
String text = s.toString();
if(!text.trim().isEmpty()){
int i;
for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
s.replace(0, i, "");
}
}
Removing at start and end (allow 1 whitespace at end for convinient input):
#Override
public void afterTextChanged(Editable s) {
int i;
//remove at start
for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
s.replace(0, i, "");
//remove at end, but allow one whitespace character
for (i = s.length(); i > 1 && Character.isWhitespace(s.charAt(i-1)) && Character.isWhitespace(s.charAt(i-2)); i--) { ; }
s.replace(i, s.length(), "");
}
For removing the space instantly you can achieve it by two ways.
One simple solution you can set the digits to your edit text.
android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
second way you can set a filter
EditText.setFilters(new InputFilter[] { filter });
InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (Character.isSpaceChar(source.charAt(i))) {
return "";
}
}
return null;
}
}
One more simple way to achieve this using the input Filter
editText.setFilters(new InputFilter[]{new InputFilter() {
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (source.toString().equalsIgnoreCase(" ")){
return "";
}
return source;
}
}});
This will remove the space entered by the user immediately and gives appearance like space is disabled.
I am using filter to set the length of editText.
I set EditText length as 10 as per following.
TextView editVew = new TextView(R.id.txtAmt);
InputFilter[] FilterArray = new InputFilter[1];
FilterArray[0] = new InputFilter.LengthFilter(10);
editVew.setFilters(FilterArray);
editVew.setInputType(InputType.TYPE_CLASS_NUMBER);
My confusion : how to set fraction of 2 digits in my number and total length of my editview should not exceed 10 digits ?
If any body knows please reply.
Thanks
Try this to make your edittext support two digits after decimals.
EditText text = (EditText) findViewById(R.id.txtAmt);
text.addTextChangedListener(new TextWatcher()
{
public void afterTextChanged(Editable edittext)
{
String str= edittext.toString();
int posDot = str.indexOf(".");
if (posDot <= 0) return;
if (str.length() - posDot - 1 > 2)
{
edt.delete(posDot + 3, posDot + 4);
}
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}
});
And use android:maxLength="10" in xml to restrict your editText support 10 maximmum input digits
Try this..
maxLength = 10;
smsType = "free";
FilterArraySeventy[0] = new InputFilter.LengthFilter(maxLength);
message.setFilters(FilterArrayten);
Solution for your Answer
amountEditText.setRawInputType(Configuration.KEYBOARD_12KEY);
amountEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
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().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, '$');
amountEditText.setText(cashAmountBuilder.toString());
// keeps the cursor always to the right
Selection.setSelection(amountEditText.getText(), cashAmountBuilder.toString().length());
}
}
});
Same Question discussed here
Ref Link
How do you create an edittext entry that formats input in money format only? When the user enters 5, I want the input to look like "$0.05" and when they then enter 3, the input should now look like "$0.53" and finally they enter 6 and the input should look like "$5.36".
ninjasense's complete solution basically works, but it has some issues:
Every time the data of the field is altered in the "onTextChanged" handler, cursor position resets to index 0 on the field, which is a bit annoying to happen when typing in monetary values.
It uses floats for formatting monetary values, which can backfire.
For the first problem I don't have solution yet, for the second one code like this works:
#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());
}
}
Building off Zds.
For keeping the cursor positioned at the end of the field use this.
cashAmountEdit.setTextKeepState(cashAmountBuilder.toString());
Selection.setSelection(cashAmountEdit.getText(), cashAmountBuilder.toString().length());
You can use a TextWatcher to do that kind of thing.
Extend 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) {
}
}
Then add it to your editText with
myEditText.addTextChangedListener(new MyTextWatcher());
I found the TextWatcher to be a bit cumbersome. Instead, you can set the key listener:
setKeyListener(new CalculatorKeyListener());
// Must be called after setKeyListener(), otherwise is overridden
setRawInputType(Configuration.KEYBOARD_12KEY);
And then create a KeyListener which extends 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 };
}
}
You then need to display the characters correctly, but that's not difficult; just keep track of cents, and then divide or multiply by 10, and use a NumberFormat to get the formatting correct.
Heres my complete solution:
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);
}
}
});
I did this but without decimal and with dot for miles, check the code and add the functionality to support decimals.
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;
}
This answer is based on Zds' answer (which in turn was based on ninjasense's answer), but this should resolve the cursor position issue:
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);
}
Notes:
The following is in a TextWatcher.onTextChanged
I'm using a different regex than other answers, which keeps the price to < $100
'view' is the editText, 'text' is the string contents
this has worked for me using an EditText with a maxLength of 6 (i.e. $00.00)