1

I have an editText that is suppose to be representative of dollar amounts. As I am trying to get the functionality of the editText working to how I want it, I am running into a lot of issues. Let me first show you what I have set up, and then I will explain my issues. Here is what I did in my xml for the editText

<EditText
    android:id="@+id/edittxtbill"
    android:layout_width="fill_parent"
    android:layout_height="38dp"
    android:textColor="@color/black"
    android:textSize="@dimen/font_mediumlarge"
    android:hint="@string/txt_hint"
    android:textColorHint="@color/black" 
    android:gravity="right" 
    android:maxLines="1" 
    android:maxLength="10"
    android:singleLine="true" 
    android:inputType="numberDecimal"
    android:digits="0123456789." >

There are a couple of things to point out. I am only allowing {0-9 and . } input. I also max the length to 10. And (although probably redundant) I limit lines to 1.

Next, my code. This is where issues occur:

1) If you input a period, without any other input this causes a crash. I fixed this by handling this specific case like

if (etBill.getText().toString().contentEquals(".")) {
                    // handle special case
                    etBill.setText("0.00"); }

2) If you input 8 values, so lets say the string in the editText is "12345678" I would receive a StackOverflowError because I am updating the value in editText in dollar amount form. So, in this scenario the editText attempts to update to 12345678.00. This is an issue because I only allow maxLength = 10. I had to handle this specific case like

// handle special case
            if (integerPlaces == 7 &&
                    etBill.getText().toString().contains(".") == false) {
                etBill.setText(strFormatted);
            }

This case was not my best, but basically before you can even input 8 integers without a decimal, it will edit the editText in the proper dollar form (strFormatted is the proper dollar format "0.00").

3) If you input more than two decimals places, this also becomes an issue. In otherwords, 1.234 is not a valid dollar format, so I had to handle that case like

// handle special case
            if (decimalPlaces >= 3) {
                etBill.setText(strFormatted);
            }

There are more cases, but I think I have provided enough to ask my question. Is this how I am suppose to program this? Case by case? This does not seem practical, because there are many exception cases. For example, what if the user tries to input two periods. I had to handle that case by changing the inputType of the editText if it already contained a period, otherwise this would cause an exception error as well.

Even more, if the user inputs 1234567.0 and then attempts to add another value to the left of the decimal, once updated to dollar form this would cause an issue too.

What is a better method? I read some information on Regex and I thought that maybe this would help prevent me from having to handle as many special cases because then I could do checks on patterns. But I do not really know, I have never used it before (and it is a bit confusing!).

My application works fine. But because I am still fairly new to programming, this approach feels sloppy. Sorry for long post, and thanks in advance!

portfoliobuilder
  • 7,556
  • 14
  • 76
  • 136

2 Answers2

2

The answer by Bart is absolutely correct. I just wanted to build on that by solving your decimal (problem)

In your edit text you are allowing the user to input more than one decimal point by explicitly setting

android:digits="0123456789."

If you remove this line, the system will prevent the user from inputting more than one dot (invalid numbers) since you are setting the

android:inputType="numberDecimal"

and you do not really need the line since you are allowing all numbers from 0-9 something like this should be sufficient for what you are trying to do.

 <EditText
            android:id="@+id/edittxtbill"
            android:layout_width="fill_parent"
            android:layout_height="38dp"
            android:hint="@string/app_name"
            android:gravity="right"
            android:inputType="numberDecimal"
            android:maxLength="10"
           />

As far as formatting it (limiting the number of decimal points) you can set a Text Watcher which will invoke method every time text is changed your edit text and then use the regex from the answer above to do the magic in onTextChanged...

Naveed
  • 2,942
  • 2
  • 25
  • 58
  • Yea, I am using the TextWatcher, but what you said about the android:digits attributes is genius! That is very useful. Thank you! I will make that change now. – portfoliobuilder Dec 30 '13 at 22:23
1

The regular expression to represent the format you want would be ([1-9]\d{0-6}|0)\.\d{2}.

What it means exactly is: Have ((a digit between 1 and 9 followed by 0 to 6 other digits) or 0), then a dot, then two digits.

However I'm not sure this is exactly the way to go for you, but that way you could check in one go whether a given input string matches the format you want. If you're going to use it, be aware that in Java you need to escape the backslashes so your pattern string would become "([1-9]\\d{0-6}|0)\\.\\d{2}"

Edit: Also have a look at this question: Android Money Input with fixed decimal where they solved the same problem slightly differently.

Community
  • 1
  • 1
Bart Enkelaar
  • 695
  • 9
  • 21
  • So that's how that works. Very nice! Like you said, it is a check in one go. I actually had another idea that I am testing now. I will try this out after I try my idea and then update you. Thank you for your response! – portfoliobuilder Dec 30 '13 at 22:04
  • I tried it and I can definately use it. But I figured out an easier and alternative method. Basically anything that causes an issue with my editText will throw an exception error. Instead of doing case by case, I am just catching the exceptions, doing a Toast to the user, and then reformatting to the proper dollar format. This way I only have to take care of three exceptions, stackoverflowerror, numberformatexception, and nullpointerexception. This pretty much sums up the 7 cases I was handling with if-then conditions. What do you think? – portfoliobuilder Dec 30 '13 at 22:10
  • 1
    Exceptions are expensive, you would want to avoid them if possible. – Naveed Dec 30 '13 at 22:22
  • I see. I'll keep my case by case then, and incorporate the regex for coming up with better conditions. Thank you for pointing that out! – portfoliobuilder Dec 30 '13 at 22:28