Android SDK Tutorial: Working With The SeekBar

In this post of our Android SDK Tutorial series I will teach you to work the seek bar. The seek bar is a slider with a maximum value with which you can select values from a range visually. The range of the seek bar is from 0 to the maximum value. So Let’s begin.

The SeekBar App: What You Will Be Making

The app you will make is one that displays the changing value of the seekbar as you drag it, also show the secondary progress shade, which will be at the value where you started the drag. The seekbar has three states: drag start, changing and drag ended, we will also make use of these.

Here is a screenshot of the seekbar example app in action.

Seekbar app: two textviews and a seekbar view

the seekbar app, two textviews and a seekbar view

The Interface: main.xml

As you can see from the photo above, our interface is nothing more than two textviews and the seekbar. One of the text labels will be used to display the seekbar’s value, the other one will be used to display the action state of the bar: changing, drag start or drag end.

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
        <TextView android:text="progress displayed here" android:textAppearance="?android:attr/textAppearanceLarge" android:id="@+id/textViewProgress" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentLeft="true"></TextView>
        <TextView android:text="action displayed here" android:textAppearance="?android:attr/textAppearanceLarge" android:id="@+id/textViewAction" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_below="@+id/textViewProgress" android:layout_alignParentLeft="true" android:layout_marginTop="16dp"></TextView>
        <SeekBar android:id="@+id/seekBar1" android:max="100" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/textView1" android:layout_alignParentLeft="true" android:layout_marginTop="26dp"></SeekBar>
        	
    </RelativeLayout>

This is how the app will look the first time you open it.

android app: a seekbar and two text labels

the seekbar app when you first open it

The Activity File: HelloWorldActivity.java

Like most views, the seekbar needs a listener. We we will implement the listener in the same class

public class HelloWorldActivity extends Activity implements OnSeekBarChangeListener

Now let’s make some objects for each of our views.

    private SeekBar bar; // declare seekbar object variable
    // declare text label objects
    private TextView textProgress,textAction;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        // load the layout
        setContentView(R.layout.main);     
        bar = (SeekBar)findViewById(R.id.seekBar1); // make seekbar object
        bar.setOnSeekBarChangeListener(this); // set seekbar listener.
        // since we are using this class as the listener the class is "this"
        
        // make text label for progress value
        textProgress = (TextView)findViewById(R.id.textViewProgress);
        // make text label for action
        textAction = (TextView)findViewById(R.id.textViewAction);
        
    }

Lastly let’s implement the required methods by the seekbar listener. The seekbar listener requires one method per action: changing, drag start, drag stop. The method bodies can be left blank but I put some stuff there to give you an idea of how they work.

Method for changing: this one gets executed as you drag the bar.

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
    		boolean fromUser) {
    	// TODO Auto-generated method stub
    	
    	// change progress text label with current seekbar value
    	textProgress.setText("The value is: "+progress);
    	// change action text label to changing
    	textAction.setText("changing");
    }

Here is what it produces:

a seekbar been dragged in an android app

this is what the onProgressChanged method does

Method for drag start: runs when you first touch the bar.

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    	// TODO Auto-generated method stub
    	textAction.setText("starting to track touch");
    	
    }

You might not even see the words "starting to track touch" since the changing method gets executed right after, but pay close attention, they are there.

Method for drag stop: runs when you let go of the bar.

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    	// TODO Auto-generated method stub
    	seekBar.setSecondaryProgress(seekBar.getProgress()); // set the shade of the previous value.
    	textAction.setText("ended tracking touch");    	
    }

the setSecondaryProgress function creates a shade value of the previous value ( the value the bar had before you started to drag it).

android slider bar with secondary progress in the background

notice the shade caused the by the setSecondaryProgress method, it has the value of what the slider was before

When you let go, the secondary progress does not disappear, it becomes the present value that’s why you can see it but it’s there.

android slider displaying the value 31

android slider after you let go of it


The full activity code is the following:

package com.yoursite.helloworld;

import android.app.Activity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class HelloWorldActivity extends Activity implements OnSeekBarChangeListener{
	private SeekBar bar; // declare seekbar object variable
	// declare text label objects
	private TextView textProgress,textAction;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        // load the layout
        setContentView(R.layout.main);     
        bar = (SeekBar)findViewById(R.id.seekBar1); // make seekbar object
        bar.setOnSeekBarChangeListener(this); // set seekbar listener.
        // since we are using this class as the listener the class is "this"
        
        // make text label for progress value
        textProgress = (TextView)findViewById(R.id.textViewProgress);
        // make text label for action
        textAction = (TextView)findViewById(R.id.textViewAction);
        
    }
    
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
    		boolean fromUser) {
    	// TODO Auto-generated method stub
    	
    	// change progress text label with current seekbar value
    	textProgress.setText("The value is: "+progress);
    	// change action text label to changing
    	textAction.setText("changing");
    }
    
    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    	// TODO Auto-generated method stub
    	textAction.setText("starting to track touch");
    	
    }
    
    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    	// TODO Auto-generated method stub
    	seekBar.setSecondaryProgress(seekBar.getProgress());
    	textAction.setText("ended tracking touch");    	
    }

}

The manifest file: AndroidManifest.xml

The seekbar does not require anything special. Here is the manifest file I used.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.yoursite.helloworld"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="8" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".HelloWorldActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>