66import android .graphics .Canvas ;
77import android .graphics .Color ;
88import android .graphics .Paint ;
9+ import android .graphics .RectF ;
910import android .util .AttributeSet ;
1011import android .view .View ;
1112
@@ -26,6 +27,7 @@ public class VuMeterView extends View {
2627 public static final int DEFAULT_BLOCK_SPACING = 20 ;
2728 public static final int DEFAULT_SPEED = 10 ;
2829 public static final int DEFAULT_STOP_SIZE = 30 ;
30+ public static final int DEFAULT_RADIUS = 0 ;
2931 public static final boolean DEFAULT_START_OFF = false ;
3032 public static final int FPS = 60 ;
3133
@@ -38,6 +40,7 @@ public class VuMeterView extends View {
3840 private float mBlockSpacing ;
3941 private int mSpeed ;
4042 private float mStopSize ;
43+ private float mCornerRadius ;
4144
4245 private Paint mPaint = new Paint ();
4346 private Random mRandom = new Random ();
@@ -83,14 +86,15 @@ private void init(AttributeSet attrs, int defStyle) {
8386 mBlockSpacing = a .getDimension (R .styleable .vumeter_VuMeterView_vumeter_blockSpacing , DEFAULT_BLOCK_SPACING );
8487 mSpeed = a .getInt (R .styleable .vumeter_VuMeterView_vumeter_speed , DEFAULT_SPEED );
8588 mStopSize = a .getDimension (R .styleable .vumeter_VuMeterView_vumeter_stopSize , DEFAULT_STOP_SIZE );
89+ mCornerRadius = a .getDimension (R .styleable .vumeter_VuMeterView_vumeter_cornerRadius , DEFAULT_RADIUS );
8690 boolean startOff = a .getBoolean (R .styleable .vumeter_VuMeterView_vumeter_startOff , DEFAULT_START_OFF );
8791 a .recycle ();
8892
8993 // Init
9094 initialiseCollections ();
9195 mPaint .setColor (mColor );
9296
93- if (startOff ){
97+ if (startOff ) {
9498 mState = STATE_PAUSE ;
9599 } else {
96100 mState = STATE_PLAYING ;
@@ -117,7 +121,7 @@ protected void onDraw(Canvas canvas) {
117121 mBlockWidth = (int ) ((mContentWidth - (mBlockNumber - 1 ) * mBlockSpacing ) / mBlockNumber );
118122
119123 // called if startOff is true
120- if (mState == STATE_PAUSE ){
124+ if (mState == STATE_PAUSE ) {
121125 int stopSize = (int ) (mContentHeight - mStopSize );
122126 for (int i = 0 ; i < mBlockNumber ; i ++) {
123127 mDestinationValues [i ] = new Dynamics (mSpeed , stopSize );
@@ -143,18 +147,13 @@ protected void onDraw(Canvas canvas) {
143147
144148 if (mDestinationValues [mBlockPass ].isAtRest () && mState == STATE_PLAYING ) {
145149 changeDynamicsTarget (mBlockPass , mContentHeight * mBlockValues [mBlockPass ][mDrawPass ]);
146- } else if (mState != STATE_PAUSE ){
150+ } else if (mState != STATE_PAUSE ) {
147151 mDestinationValues [mBlockPass ].update ();
148152 }
149153
150154 mTop = mPaddingTop + (int ) (mDestinationValues [mBlockPass ].getPosition ());
151-
152- canvas .drawRect (
153- mLeft ,
154- mTop ,
155- mRight ,
156- mContentHeight ,
157- mPaint );
155+ RectF rect = new RectF (mLeft , mTop , mRight , mContentHeight );
156+ canvas .drawRoundRect (rect , mCornerRadius , mCornerRadius , mPaint );
158157 }
159158
160159 this .postInvalidateDelayed (1000 / FPS );
@@ -209,7 +208,7 @@ private int incrementAndGetDrawPass() {
209208 return mDrawPass ;
210209 }
211210
212- private void initialiseCollections (){
211+ private void initialiseCollections () {
213212 mBlockValues = new float [mBlockNumber ][DEFAULT_NUMBER_RANDOM_VALUES ];
214213 mDestinationValues = new Dynamics [mBlockNumber ];
215214
@@ -299,10 +298,10 @@ public void setSpeed(int speed) {
299298
300299 /**
301300 * Pause the player.
302- *
301+ * <p>
303302 * Call {@link #resume(boolean)} to replay the VuMeter
304303 */
305- public void pause (){
304+ public void pause () {
306305 mState = STATE_PAUSE ;
307306 }
308307
@@ -311,23 +310,23 @@ public void pause(){
311310 *
312311 * @param withAnimation if you want to have an animation from current state to stop state
313312 */
314- public void stop (boolean withAnimation ){
315- if (mDestinationValues == null ){
313+ public void stop (boolean withAnimation ) {
314+ if (mDestinationValues == null ) {
316315 initialiseCollections ();
317316 }
318317 mState = STATE_STOP ;
319318 int collapseSize = (int ) (mContentHeight - mStopSize );
320319
321320 // Prevent NPE in the destinations table is empty
322- if (mDestinationValues .length <= 0 ){
321+ if (mDestinationValues .length <= 0 ) {
323322 return ;
324323 }
325324
326- for (int i = 0 ; i < mBlockNumber ; i ++){
327- if (mDestinationValues [i ] == null ){
325+ for (int i = 0 ; i < mBlockNumber ; i ++) {
326+ if (mDestinationValues [i ] == null ) {
328327 continue ;
329328 }
330- if (withAnimation ){
329+ if (withAnimation ) {
331330 mDestinationValues [i ].setTargetPosition (collapseSize );
332331 } else {
333332 mDestinationValues [i ].setPosition (collapseSize );
@@ -340,19 +339,37 @@ public void stop(boolean withAnimation){
340339 *
341340 * @param withAnimation if you want to have transition from stop to resume state, set to true
342341 */
343- public void resume (boolean withAnimation ){
344- if (mState == STATE_PAUSE ){
342+ public void resume (boolean withAnimation ) {
343+ if (mState == STATE_PAUSE ) {
345344 mState = STATE_PLAYING ;
346345 return ;
347346 }
348347
349348 mState = STATE_PLAYING ;
350349
351- if (!withAnimation ){
352- for (int i = 0 ; i < mBlockNumber ; i ++){
350+ if (!withAnimation ) {
351+ for (int i = 0 ; i < mBlockNumber ; i ++) {
353352 mDestinationValues [i ].setPosition (mContentHeight * mBlockValues [i ][mDrawPass ]);
354353 changeDynamicsTarget (i , mContentHeight * mBlockValues [i ][mDrawPass ]);
355354 }
356355 }
357356 }
357+
358+ /**
359+ * Get the current corner radius
360+ *
361+ * @return the corner radius
362+ */
363+ public float getCornerRadius () {
364+ return mCornerRadius ;
365+ }
366+
367+ /**
368+ * Set the current corner radius
369+ *
370+ * @param radius The desired corner radius
371+ */
372+ public void setSpeed (float radius ) {
373+ mCornerRadius = radius ;
374+ }
358375}
0 commit comments