Install a Change Listener into a SeekBar

An SeekBar is a slider. In response to a drag, something will call the onProgressedChanged method of the SeekBar.OnSeekBarChangListener object that was plugged into the SeekBar. This method receives the current position of the seekbar and interprets it as a Celsius temperature in the range 0 to 100 inclusive. The temperature is displayed in the TextView below the SeekBar.

The only method of the listener that I want to write is onProgressedChanged, but Java forces me to write all three methods. The textView variable in onCreate had to be final because it is mentioned in onProgressChanged.

Source code in SeekBar.zip

  1. MainActivity.java. textView had to be final to allow us to mention it in a method of the inner class.
  2. activity_main.xml. The TextView’s typeface is monospace to prevent the text from jumping horizontally when the temperature changes.
  3. strings.xml. \u00B0 is the degree symbol °. Because of the percent signs, the format string needed the non-android: attribute formatted="false" to avoid the error message “Multiple substitutions specified in non-positional format; did you mean to add the formatted="false" attribute?” See Formatting and Styling.
  4. AndroidManifest.xml
  5. build.gradle (Module: app)

Documentation

  1. Sliders in Material design
  2. Class android.widget.SeekBar
    1. Documentation
    2. Source code at platform_frameworks_base/core/java/android/widget/SeekBar.java
  3. Class android.widget.SeekBar.OnSeekBarChangeListener
    1. Documentation
    2. Source code at platform_frameworks_base/core/java/android/widget/SeekBar.java, line 38

SeekBars in ApiDemos

  1. Views → Seek Bar
    1. ApiDemos/src/com/example/android/apis/view/SeekBar1.java
      Class com.example.android.apis.view.SeekBar1 is a subclass of class Activity. Its onCreate method installs a SeekBar.OnSeekBarChangeListener into the SeekBar. The SeekBar.OnSeekBarChangeListener has all three methods.
    2. ApiDemos/res/layout/seekbar_1.xml
      creates a vertical LinearLayout containing a SeekBar and two TextViews.
    3. ApiDemos/res/values/strings.xml contains three string resources:
      1. seekbar_from_touch (line 975)
      2. seekbar_tracking_on (line 973)
      3. seekbar_tracking_on (line 974)
    4. ApiDemos/AndroidManifest.xml lists class SeekBar1 on line 2368.

  2. Views → Rotating Button
    TX and TY set the horizontal and vertical translation. SX and SY set the horizontal and vertical scale. X, Y, and Z set the rotations around the X, Y, and Z axes. This demo should have used an ImageView instead of a Button.
    1. ApiDemos/src/com/example/android/apis/view/RotatingButton.java
      Class com.example.android.apis.view.RotatingButton is a subclass of class Activity. Its onCreate method installs seven SeekBar.OnSeekBarChangeListeners into the seven SeekBars.
    2. ApiDemos/res/layout/rotating_view.xml
      creates a vertical LinearLayout containing three horizontal LinearLayouts and a Button. The horizontal LinearLayouts contain a total of seven SeekBars.
    3. ApiDemos/AndroidManifest.xml lists class RotatingButton on lines 2474–2479.

Things to try

  1. Let the format argument of String.format be a string resource in res/values/strings.xml.

  2. Our SeekBar is dragged around by a finger. It is also possible for a SeekBar to be moved by the app itself. See setProgress and the third argument of onProgressedChanged.

  3. Change the background color of the SeekBar and the text color of the TextView as the user drags. Make them bluer for colder, redder for hotter. Add the following static method to class MainActivity.
        //Convert a celsius temperature in the ange 0 to 100 inclusive into a color:
        //a mixture of red for hot, blue for cold.
    
        private static int celsiusToColor(int celsius) {
            //Clamp an out-of-range temperature to the range from freezing to boiling.
            if (celsius < 0) {
                celsius = 0;
            } else if (celsius > 100) {
                celsius = 100;
            }
    
            int red = 255 * celsius / 100;
            int blue = 255 - red; //as red increases, blue decreases.  And vice versa.
            return Color.rgb(red, 0, blue);
        }
    
    In onCreate and onProgressChanged,
            seekBar.setBackgroundColor(celsiusToColor(celsius));
            textView.setTextColor(celsiusToColor(celsius));