User login



Syndicate content
Add to Google


Custom View - HorizontalSlider

SDK Version: 
M5


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:

  1. public interface OnProgressChangeListener {
  2.     void onProgressChanged(View v, int progress);
  3. }

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:

  1. public class HorizontalSlider extends ProgressBar {
  2.  
  3.     private OnProgressChangeListener listener;
  4.  
  5.     private static int padding = 2;
  6.  
  7.     public interface OnProgressChangeListener {
  8.         void onProgressChanged(View v, int progress);
  9.     }
  10.    
  11.     public HorizontalSlider(Context context, AttributeSet attrs,
  12.             Map inflateParams, int defStyle) {
  13.         super(context, attrs, inflateParams, defStyle);
  14.     }
  15.  
  16.     public HorizontalSlider(Context context, AttributeSet attrs,
  17.             Map inflateParams) {
  18.         super(context, attrs, inflateParams, android.R.attr.progressBarStyleHorizontal);
  19.  
  20.     }
  21.  
  22.     public HorizontalSlider(Context context) {
  23.         super(context);
  24.  
  25.     }
  26.  
  27.     public void setOnProgressChangeListener(OnProgressChangeListener l) {
  28.         listener = l;
  29.     }
  30.  
  31.     @Override
  32.     public boolean onTouchEvent(MotionEvent event) {
  33.  
  34.         int action = event.getAction();
  35.  
  36.         if (action == MotionEvent.ACTION_DOWN
  37.                 || action == MotionEvent.ACTION_MOVE) {
  38.             float x_mouse = event.getX() - padding;
  39.             float width = getWidth() - 2*padding;
  40.             int progress = Math.round((float) getMax() * (x_mouse / width));
  41.  
  42.             if (progress < 0)
  43.                 progress = 0;
  44.  
  45.             this.setProgress(progress);
  46.  
  47.             if (listener != null)
  48.                 listener.onProgressChanged(this, progress);
  49.  
  50.         }
  51.  
  52.         return true;
  53.     }
  54. }

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.

Comments

Submitted by Anonymous (not verified) on Wed, 02/13/2008 - 19:00.

nice tutorial, but how can i get the progressBar without that circle delivered with android? just the new bar?

Submitted by revcom (not verified) on Sun, 02/10/2008 - 17:16.

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

Submitted by hobbs on Sun, 02/10/2008 - 18:08.

Thank you!! Updated the tutorial and bug report!

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
Because you are not logged in, we must determine if you are a human or an Android designed to spam the internet. (Hint: All characters are lowercase)
  _        __               
| |__ / _| __ __ ___
| '_ \ | |_ \ \/ / / __|
| | | | | _| > < | (__
|_| |_| |_| /_/\_\ \___|
Enter the code depicted in ASCII art style.