Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - set a ProgressBar to be a vertical bar instead of horizontal?

Tags:

android

I am trying to use a ProgressBar as a metering like display. I thought it was going to be an easy task and thought that ProgressBar had a property to set to be vertical, but I'm not seeing anything.

Additionally I'd like to be able to show ruler like indicator along the side of the bar to clearly indicate the current level.

Pointers appreciated - Thanks!

like image 962
bursk Avatar asked Oct 13 '10 17:10

bursk


2 Answers

I had recently come across the need for a vertical progress bar but was unable to find a solution using the existing Progress Bar widget. The solutions I came across generally required an extension of the current Progress Bar or a completely new class in it self. I wasn't convinced rolling out a new class to achieve a simple orientation change was necessary.

This article presents a simple, elegant, and most importantly, a no-hack solution to achieving a vertical progress bar. I'm going to skip the explanation and simply provide a cookie cutter solution. If you require further details feel free to contact me or leave a comment below.

Create an xml in your drawable folder (not drawable-hdpi or drawable-mdpi -- place it in drawable). For this example I call my xml vertical_progress_bar.xml

Here's what to place in the xml file:

<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">   <item android:id="@android:id/background">     <shape>       <corners android:radius="5dip" />       <gradient         android:startColor="#ff9d9e9d"         android:centerColor="#ff5a5d5a"         android:centerY="0.75"         android:endColor="#ff747674"         android:angle="180"       />     </shape>   </item>   <item android:id="@android:id/secondaryProgress">     <clip android:clipOrientation="vertical" android:gravity="bottom">       <shape>         <corners android:radius="5dip" />         <gradient           android:startColor="#80ffd300"           android:centerColor="#80ffb600"           android:centerY="0.75"           android:endColor="#a0ffcb00"           android:angle="180"         />       </shape>     </clip>   </item>   <item android:id="@android:id/progress">     <clip android:clipOrientation="vertical" android:gravity="bottom">       <shape>         <corners android:radius="5dip" />         <gradient           android:startColor="#ffffd300"           android:centerColor="#ffffb600"           android:centerY="0.75"           android:endColor="#ffffcb00"           android:angle="180"         />       </shape>     </clip> </item> </layer-list> 

Create an xml file called styles.xml and place it in res/values. If your project already contains styles.xml in res/values then skip this step.

Modify your styles.xml file and append the following code to the end of the file:

<style name="Widget"> </style> <style name="Widget.ProgressBar">   <item name="android:indeterminateOnly">true</item>   <item name="android:indeterminateBehavior">repeat</item>   <item name="android:indeterminateDuration">3500</item>   <item name="android:minWidth">48dip</item>   <item name="android:maxWidth">48dip</item>   <item name="android:minHeight">48dip</item>   <item name="android:maxHeight">48dip</item> </style> <style name="Widget.ProgressBar.Vertical">   <item name="android:indeterminateOnly">false</item>   <item name="android:progressDrawable">@drawable/progress_bar_vertical</item>   <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>   <item name="android:minWidth">1dip</item>   <item name="android:maxWidth">12dip</item> </style> 

Add your new vertical progress bar to your layout. Here's an example:

<ProgressBar   android:id="@+id/vertical_progressbar"   android:layout_width="12dip"   android:layout_height="300dip"   style="@style/Widget.ProgressBar.Vertical" /> 

That should be all you need to do to make use of a vertical progress bar in your project. Optionally, you might have custom drawable nine-patch images that you are using for the progress bar. You should make the appropriate changes in the progress_bar_vertical.xml file. I hope this helps you out in your project!

like image 141
jagsaund Avatar answered Sep 29 '22 07:09

jagsaund


You have to create your own custom progressbar.

In your xml add this layout:

 <com.example.component.VerticalProgressBar          style="?android:attr/progressBarStyleHorizontal"         android:id="@+id/verticalRatingBar1"         android:layout_width="wrap_content"         android:progress="50"         android:layout_height="fill_parent" /> 

VerticalProgressBar.java

public class VerticalProgressBar extends ProgressBar{     private int x, y, z, w;      @Override     protected void drawableStateChanged() {         // TODO Auto-generated method stub         super.drawableStateChanged();     }      public VerticalProgressBar(Context context) {         super(context);     }      public VerticalProgressBar(Context context, AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle);     }      public VerticalProgressBar(Context context, AttributeSet attrs) {         super(context, attrs);     }      protected void onSizeChanged(int w, int h, int oldw, int oldh) {         super.onSizeChanged(h, w, oldh, oldw);         this.x = w;         this.y = h;         this.z = oldw;         this.w = oldh;     }      @Override     protected synchronized void onMeasure(int widthMeasureSpec,             int heightMeasureSpec) {         super.onMeasure(heightMeasureSpec, widthMeasureSpec);         setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());     }      protected void onDraw(Canvas c) {         c.rotate(-90);         c.translate(-getHeight(), 0);         super.onDraw(c);     }      @Override     public boolean onTouchEvent(MotionEvent event) {         if (!isEnabled()) {             return false;         }          switch (event.getAction()) {         case MotionEvent.ACTION_DOWN:              setSelected(true);             setPressed(true);             break;         case MotionEvent.ACTION_MOVE:             setProgress(getMax()                     - (int) (getMax() * event.getY() / getHeight()));             onSizeChanged(getWidth(), getHeight(), 0, 0);              break;         case MotionEvent.ACTION_UP:             setSelected(false);             setPressed(false);             break;          case MotionEvent.ACTION_CANCEL:             break;         }         return true;     }      @Override     public synchronized void setProgress(int progress) {          if (progress >= 0)             super.setProgress(progress);          else             super.setProgress(0);         onSizeChanged(x, y, z, w);      } } 

Or : Jagsaund solution is also being perfect.

like image 28
Ramesh Akula Avatar answered Sep 29 '22 07:09

Ramesh Akula