Custom View - HorizontalSlider
Introduction
In this tutorial we'll create a custom View called HorizontalSlider based on ProgressBar. This slider will allow the user to move the slider back and forth on the screen and get notified when this happens.

Click here to download the complete source.
Creating an interface
First think we'll want to do is create an interface to use to notify our Activities when a user changes the value of the slider. We'll call this interface OnProgressChangeListener to match the naming conventions of some of the other interfaces used in Android. Here is our interface:
- public interface OnProgressChangeListener {
- }
Interfaces do not do anything, they just create an outline that you must use to implement an object later.
Creating the view
Creating the view in this case is very easy. All that we must do is create a class that extends ProgressBar. After we create this class we will just need to override the constructors and the onMotionEvent() method.
Tip:To override the constructors in Eclipse you can right click in the class's block and hit Source->Generate Constructors from Superclass
All that we must do in the constructors is set our progress bar's background to be the progress_horizontal drawable that is built into android, this will make it a horizontal progress bar instead of the circular one.
Here is the HorizontalSlider class:
- public class HorizontalSlider extends ProgressBar {
- private OnProgressChangeListener listener;
- private static int padding = 2;
- public interface OnProgressChangeListener {
- }
- super(context, attrs, inflateParams, defStyle);
- }
- super(context, attrs, inflateParams, android.R.attr.progressBarStyleHorizontal);
- }
- super(context);
- }
- public void setOnProgressChangeListener(OnProgressChangeListener l) {
- listener = l;
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- int action = event.getAction();
- if (action == MotionEvent.ACTION_DOWN
- || action == MotionEvent.ACTION_MOVE) {
- float x_mouse = event.getX() - padding;
- float width = getWidth() - 2*padding;
- if (progress < 0)
- progress = 0;
- this.setProgress(progress);
- if (listener != null)
- listener.onProgressChanged(this, progress);
- }
- return true;
- }
- }
First we include our interface as a member class of this view. Then we setup the 3 constructors, having the second one pass in a style for the horizontal progress bar.
Next we create a function setOnProgressChangeListener() so that when you use this code you can use the interface created above to monitor changes in the progress level. We'll save this to our private variable named "listener".
Now, all the work happens starting on line 42 in our onTouchEvent() class. This class is notified when the user is clicking or dragging a click.
This method is pretty simple, we just calculate what the progress is based on the width of the progress bar and the x value for the click. I have created a static paddedPixels variable that will offset our clicks and widths because there is about 2 pixels of unused space on each side of the bar.
After we set our progress we can also call our OnProgressChangeListener's onProgressChanged() method to notify interested parties that the progress has changed.
On the next page we'll figure out how to use this new object.
<!--pagebreak-->
Using HorizontalSlider
You can use HorizontalSlider just like any ProgressBar. In this example I'm going to utilize the new ProgresBar that is built into the title of the application and a HorizontalSlider. When the user clicks to change the HorizontalSlider value I'll update the ProgressBar in the title to show that it's working. Here is the main.xml layout I've used for this example:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:paddingLeft="10dip"
- android:paddingRight="10dip"
- android:paddingTop="100dip"
- android:gravity="center_horizontal" >
- <com.helloandroid.android.horizontalslider.HorizontalSlider
- android:id="@+id/slider"
- android:layout_width="250dip"
- android:layout_height="20dip"
- android:max="10000"
- android:layout_centerHorizontal="true" />
- </LinearLayout>
Now, we can create a simple Activity for this layout. Here is SliderTest.java:
- public class SliderTest extends Activity {
- private HorizontalSlider slider;
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- setContentView(R.layout.main);
- setProgressBarVisibility(true);
- slider = (HorizontalSlider) this.findViewById(R.id.slider);
- slider.setOnProgressChangeListener(changeListener);
- }
- private OnProgressChangeListener changeListener = new OnProgressChangeListener() {
- setProgress(progress);
- }
- };
- }
In our onCreate() function we request that the title progress bar feature is enabled with the requestWindowFeature() method. Then all we have to do is create a OnProgressChangeListener for the slider and update the progress bar from there!
You can do anything you want with custom views, in this case it was a very simple change to a built in view, but don't limit yourself to the ones that were handed to us.
Good luck!

Comments
How To Load Android On HP PDA 3870
Dear Gurus
How to load Android OS on to HP IPaq 3870
Best Regards
Dayal
Singapore
nice tutorial, but how can i
nice tutorial, but how can i get the progressBar without that circle delivered with android? just the new bar?
FIX: Dragging bug
Hi there,
You need to return true from your onMotionEvent in order for mouse dragging to work. Replace the "return super.onMotionEvent(event)" with "return true" (line 60) and it works beautifully.
Thanks for the great control.
Robert
Thanks!
Thank you!! Updated the tutorial and bug report!