glaukon
Chapter 3: Java - Part 16
Now that our app can handle basic addition, let's get it to start incorporating the tip too. That's the whole purpose of our app, after all. To get started, let's bring to bear some of the objects we'll be using. Declare the following variables in MainActivity:

private double tipPercentValue;

private EditText tipPercent;

private SeekBar tipSlider;

We want a double to hold the value of our tip percentage, as well as access to the EditText and SeekBar objects in the tipping portion of our app. Since this is the first SeekBar we've had in MainActivity, you'll need this import statement:
import android.widget.SeekBar;
Then, assign these variables some values, as below:

tipPercentValue = 0.15;

tipPercent = (EditText) findViewById(R.id.tipPercent);

tipSlider = (SeekBar) findViewById(R.id.tipSlider);

The default tip is 15%. Now, in order to get the SeekBar working, we need to implement another kind of listener. So do this:
public class MainActivity extends Activity implements OnClickListener, OnFocusChangeListener, OnSeekBarChangeListener {
And the import is:
import android.widget.SeekBar.OnSeekBarChangeListener;
The new listener is the OnSeekBarChangeListener. You already have a good idea of how listeners work, so you can probably guess what this does. The OnSeekBarChangeListener interface allows MainActivity to notice whenever a SeekBar that it's listening to changes. Now implement OnSeekBarChangeListener's methods. Again, you can use Eclipse to do this automatically, if you want.

@Override

public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

// TODO Auto-generated method stub

}


@Override

public void onStartTrackingTouch(SeekBar seekBar) {

// Not needed.

}


@Override

public void onStopTrackingTouch(SeekBar seekBar) {

// Not needed.

}

We will not be using the onStartTrackingTouch and onStopTrackingTouch methods, so we can leave them empty. We're only concerned with the onProgressChanged method. The onProgressChanged method is called whenever the computer detects that a SeekBar being listened to has changed. Normally, this will be because the user interacted with the SeekBar. It gets passed 3 arguments automatically. The first is the SeekBar that changed. The second is the new value, or progress, of the SeekBar, as an integer. The third is a boolean that is true if the user changed the SeekBar, and false if the app itself changed the SeekBar.
Before continuing, make sure MainActivity is listening to tipSlider.
tipSlider.setOnSeekBarChangeListener(this);
Now make your onProgressChanged method look like this:

@Override

public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

if (seekBar == tipSlider) {

tipPercentValue = progress;

tipPercent.setText(String.format("%.0f", tipPercentValue) + "%");

tipPercentValue = tipPercentValue / 100;

}

}

Let's go over this. First, an if conditional. It checks to make sure the SeekBar that was changed is tipSlider. Technically, since we only have 1 SeekBar, we don't need to make sure it's tipSlider. But it's a good habit of getting into, and matches the structure of our other listening methods.
Inside the if block, we set tipPercentValue equal to the progress of tipSlider (which was passed automatically). The progress refers to how far along the SeekBar the little slider widget is. Next, we set tipPercent's Text to the value of tipPercentValue, formatted into a string with 0 decimal places, no commas (since the tip percentage will likely never get into the thousands), and with a % added to the end of it. After that, we have to set tipPercentValue to 1/100th of itself, by dividing it by 100. This is because we want tipPercentValue to stay as a percentage, not a whole number. But since progress is an int, we need to divide its return value by 100. In short, the user sees the tip percent as a whole number (15%), but our code needs to use an actual percentage number (0.15). Finally, note that we don't ever need to use the boolean fromUser here, which is fine. You don't always have to use all the arguments that are passed.
Cool cats. Test the app.
As you can see, when you slide tipSlider around, the EditText tipPercent will now change accordingly. Unfortunately, our app doesn't yet use the tip information in its calculations. So that's the next thing we need to work on.
Glossary
OnSeekBarChangeListener: OnSeekBarChangeListener is an interface that can detect when SeekBars' progresses are changed.
onProgressChanged(SeekBar seekBar, int progress, boolean fromUser): The onProgressChanged method is automatically called whenever a SeekBar an OnSeekBarChangeListener is listening to is changed. It is similar to the onClick and onFocusChanged methods we've already used.