glaukon
Chapter 3: Java - Part 15
We want to make sure that whenever we're calculating the total for any particular Diner, we remove any dollar signs that may be in the order EditTexts. Now, we can do this within the updateTotal method. However, since the updateTotal method is already getting a little bit complicated (especially the Double.parseDouble line), let's create a new method that will exist soley to convert an EditText to a double. We can then use that method inside updateTotal. This keeps things a little more organized, I think. Create the following method in the Diner class:

public double editTextToDouble(EditText et) {

double db = 0.0;

db = Double.parseDouble(et.getText().toString().replace("$", "").replace(",", ""));

return db;

}

As you can see, this method takes an EditText as an argument. Then, it creates a new double variable, db. I haven't really talked much about it before, but when you create a new variable inside a method, that variable only lasts until the end of the method. So when the editTextToDouble method finishes, the variable db will no longer exist (and soon, the double it refers to will also cease to exist, though I probably won't get into those details in this tutorial). What's more, you're allowed to use the same variable name in multiple different methods. So if you wanted, you could have a variable called db in the Diner class, the updateTotal method, and the editTextToDouble method, and that would be fine, technically. It would, of course, be very confusing, so don't do that. But just fyi, that's how variables within methods work. This relates to the concept of scope, but I think I'll cover that in the next tutorial.
Anyway, the method then converts the EditText it's passed into a string, and uses the replace method to remove any dollar signs and commas from that string. The replace method takes 2 arguments, and is used on strings. It removes all occurrences of the first argument inside a string, and replaces them with the second argument. So let's say we have $0.00 as our string. If we used .replace("$","") on that string, we would get 0.00. The thing we want to replace (the first argument) is a dollar sign. The thing we want to replace it with (the second argument) is an empty string, or nothing. As far as I know, there isn't a method to just straight up remove a character, so we have to use this workaround of replacing something we want to delete with nothing. After the first replace method, we have another one, that does the same thing, except with commas. We also want to remove commas from the order EditTexts, since Double.parseDouble can't handle commas either. Right now, there's not way for the order EditTexts to even have commas (since the user can't enter them himself), but that'll change soon. Also, you may want to know that the arguments the replace method takes are chars (for characters), not strings. A char is just a single character, while a string can be 0 or more characters.
Once we've gotten rid of the dollar signs and commas, we use Double.parseDouble to get a double. We then return that double. Again, return just means to tell the computer something. With that done, change the updateTotal method so it looks like this:

public void updateTotal(EditText toBeUpdated) {

total = 0.0;

toBeUpdated.setText("$" + String.format("%,.02f", editTextToDouble(toBeUpdated)));

for (int i = 0; i < orderList.size(); i++) {

total += editTextToDouble(orderList.get(i));

}

tvSplitBill.setText("$" + String.format("%,.2f", total));

}

Okay, so a couple of things changed here. First, you'll notice we gave updateTotal an argument called toBeUpdated. Actually, technically, it's a parameter. Basically, you call them parameters when you define the method, and call them arguments when you use the method. It's not too important. Anyway, we're making updateTotal accept an EditText as an argument. Specifically, it will be the order EditText that just lost focus. This way, we can properly format order EditTexts whenever a user edits one. We do this in the third line above. We take toBeUpdated and use the editTextToDouble method we just wrote on it. The editTextToDouble will return the double version of whatever number was in toBeUpdated. We then format that double with String.format, thus making it a string. After that, we add a dollar sign to the front of that string. Finally, we set toBeUpdated's Text property to this new string. In short, this line just makes sure that the order EditTexts all have dollar signs and standardized formatting, regardless of what the user put in. This is nice because the user doesn't have the option of putting in dollar signs and commas himself when he's editing a Number (Decimal) EditText. In case you're wondering, we purposely limit the input type to numbers so that the user is less able to screw around with inputs.
Under that, we have the for loop from before. Except this time, instead of the relatively messy Double.parseDouble line we had before, we again make use of our editTextToDouble method to make this line a lot cleaner. Finally, we set the Text of tvSplitBill as before. At this point, if you save the Diner class, you'll probably notice that Eclipse takes issue with a line in MainActivity. So let's go back there now.
Since we gave updateTotal a new parameter just now, we need to make sure we pass it an argument when we use it in MainActivity. So find the line where we have the updateTotal method, and replace it with this:
dinerList.get(i).updateTotal((EditText) v);
We're in the onFocusChange method, so v refers to the View that had its focus changed. Of course, v is technically a View, and we said updateTotal needs to take an EditText as an argument. Therefore, we need to cast v as an EditText. Okay, let's test this.
What you should notice is that order EditTexts with dollar signs still in them that lose focus no longer crash the app. Moreover, after you finish editing an EditText, our app will format it for us.
Glossary
Char: A char is a data type that is a single character.
replace(char oldChar, char newChar): The replace method replaces all occurrences of the first argument with the second argument in the string it is called on.
Parameter: Basically, when you declare a method, you have to set what arguments it can take. When you're talking about arguments in this sense, the word to use is parameters. Alternatively, you can think of parameters as sockets, and arguments as things that plug into the sockets. Sort of. Or just read the Wikipedia page.