glaukon
Chapter 3: Java - Part 19
Anyway, let's move on. Right now, tipSlider works fine when you use it. However, when you input text into the tipPercent EditText, nothing happens. So let's change that.
We want tipSlider to automatically jump to the correct location if the user elects to edit tipPercent instead of dragging tipSlider. We also want all the amounts in the split bill to update using the new tip percentage in tipPercent. So, first thing's first, let's listen to tipPercent using an OnFocusChangeListener.
tipPercent.setOnFocusChangeListener(this);
Next, go down to the onFocusChange code. Make it look like this:

if (v == tipPercent && hasFocus == false) {

tipPercentValue = Double.parseDouble(((EditText) v).getText().toString().replace("%", ""));

if (tipPercentValue > 50) {

tipPercentValue = 50.0;

}

tipSlider.setProgress((int) tipPercentValue);

} else {

...

}

}

Here, the ... represents all the code that previously existed in onFocusChange (that is, all that stuff for order EditTexts). We've added an if block before that, and we only want the old onFocusChange code to execute if that if statement fails. The if statement checks whether or not the View that triggered onFocusChange was tipPercent, and whether or not it lost focus. If either of those is false, the computer goes on and checks the order EditText stuff we wrote before. However, if both are true, we know that tipPercent lost focus, and not any other View, so we need to deal with a possible change in the tip.
Thus, inside the if block, we set tipPercentValue to whatever the user changed tipPercent to. Again, we need to do some adjusting here, like getting rid of the %, if it exists, before using Double.parseDouble. Also, make sure to cast v as an EditText. (Alternatively, replace v with tipPercent, which works just as well.) Next, we have another if block. This one checks to see if the user tried to set a higher tip percentage than 50%. If so, we bring tipPercentValue back down to 50. Basically, it's generally a good idea to have an limits in your code, which helps reduce bugs, and 50% for tip at a restaurant is a very reasonable upper limit, I think. After that, we have a new method, setProgress. You use setProgress on SeekBars, and it does what you would think it does. It takes an integer as an argument, and sets the progress of a SeekBar to that integer. We use it here to set it to tipPercentValue, which reflects whatever the user input in tipPercent. Since tipPercentValue is a double, we need to cast it as an int.
And that's all we need to do for that. If you're wondering, no, we don't need to call updateTotal on all the Diners, or do anything else, since as soon as we use the setProgress method, we trigger the onProgressChanged method we wrote earlier. That means once the computer gets to this setProgress line, it will then jump to the onProgressChanged code and do all that stuff related to tip calculation. Thus, we avoid writing duplicate code, which is nice. Note that the stuff inside our onProgressChanged method will activate regardless of whether the user changed the SeekBar using his finger, or the programmer, using setProgress. If you wanted the onProgressChanged stuff to only happen when the user changed the SeekBar, or only when the programmer changed it, you can make use of the fromUser boolean. Again, we don't need or want that here, so we didn't use it.
Okay, test the app. Change the tip using the tipPercent EditText, rather than tipSlider. Doing so should move tipSlider accordingly, as well as update the amounts in the split bill. Also, if you use a number larger than 50, the app will force the tip back down to 50%. I'll spare you a screenshot here, and just move on.
Glossary
setProgress(int progress): The setProgress method sets the progress of a SeekBar to whatever is passed as an argument.