Android GaugeView library

Evelina Vrabie

Dedicated coder, occasional blogger, hackathon goer and friendly team mate.

You may also read...

  • Amir Hossein

    it’s crashes on landscape mode, why?

  • Neruja

    I’m trying to make Signal meter with dBm value. How can I change the start and the end value. It shoule start with -94 dBm (very bad signal) and end at 0 dBm (excellent signal strength).

  • Erwin G

    Hi, thanks for sharing this!!

    I had some troubles to with scaleStartValue 100.

    I had to change this lines:

    Line 238 (comments of Edilson Mendes)
    final String[] ranges = res.getStringArray(R.array.ranges);
    final String[] colors = res.getStringArray(R.array.rangeColors);
    to
    final String[] ranges = res.getStringArray(rangesId);
    final String[] colors = res.getStringArray(colorsId);

    Line 683:
    float div = mScaleEndValue / (float) mDivisions;
    float mod = value % div;
    to
    float div = (mScaleEndValue – mScaleStartValue) / (float) mDivisions;
    float mod = (value – mScaleStartValue) % div;

    Lines 704
    return tick * (mDivisionValue / mSubdivisions);
    to
    return mScaleStartValue + (tick * (mDivisionValue / mSubdivisions));

    I am working with Android Studio and had to change the namespace (xmlns:gauge=”http://schemas.android.com/apk/res-auto”) to get the attributes (like scaleStartValue) working. Without this change the default values were applied.
    (See http://stackoverflow.com/questions/6471742/android-library-project-uses-declare-styleable-how-to-compile)

    Hopefully this will help other users with thee same problems…

    • BThadium

      Hope you’ll see this comment.
      I’m unable to make it work with your modifications.
      Modifications @ line 683 are rejected by Android Studio.

      Could you please give a more complete explanation?
      Thanks a lot!

      • Erwin G

        Sorry, I didn’t get any message when you added your reply….. Sorry for the late response.

        I don’t know what you mean by “rejected by Android Studio”.

        I can give you a short explanation:
        float div = (mScaleEndValue – mScaleStartValue) / (float) mDivisions;
        float mod = (value – mScaleStartValue) % div;
        means that the drawing area is rotated. Instead of starting on 0 degrees you recalculate the angle to mScaleStartValue. “div” is the total number of degrees per scaledivision. With “mod” you calculate the desired drawing angle. If you enter mScaleStartValue=0 then you get the original formulas.

        For line 704 the explanation is likewise: you have to use an offset when the starting angle is not equal to 0.

        But even if you understand this explanation (without figures/an image) I don’t know if this will solve you “rejected by Studio” problem. I hope you have found a solution….

  • Pingback: Is there any idea to make gauge chart in android | Android Questions()

  • AdoHus

    Suggestion: It would be nice if the start and end value of the scale could be set by a method.

  • Luke

    Is it possible to get the needle working on the second gauge? And with a different needle colour? Thanks.

  • Or Kazaz

    I can’t get it to work!! please help!
    When using this:

    I get this error:

    java.lang.ArrayIndexOutOfBoundsException: 3
    at android.graphics.Gradient_Delegate$GradientPaint.precomputeGradientColors(Gradient_Delegate.java:110)
    at android.graphics.RadialGradient_Delegate$RadialGradientPaint.createContext(RadialGradient_Delegate.java:128)
    at apple.awt.OSXSurfaceData.setupPaint(OSXSurfaceData.java:751)
    at apple.awt.OSXSurfaceData.setupGraphicsState(OSXSurfaceData.java:1038)
    at apple.awt.OSXSurfaceData.setupGraphicsState(OSXSurfaceData.java:1004)
    at apple.awt.OSXSurfaceData.doOval(OSXSurfaceData.java:1283)
    at apple.awt.CRenderer.fillOval(CRenderer.java:273)
    at apple.awt.CRenderer.fillOval(CRenderer.java:261)
    at sun.java2d.pipe.ValidatePipe.fillOval(ValidatePipe.java:90)
    at sun.java2d.SunGraphics2D.fillOval(SunGraphics2D.java:2398)
    at android.graphics.Canvas_Delegate$5.draw(Canvas_Delegate.java:708)
    at com.android.layoutlib.bridge.impl.GcSnapshot.drawInLayer(GcSnapshot.java:613)
    at com.android.layoutlib.bridge.impl.GcSnapshot.draw(GcSnapshot.java:583)
    at android.graphics.Canvas_Delegate.draw(Canvas_Delegate.java:1190)
    at android.graphics.Canvas_Delegate.native_drawOval(Canvas_Delegate.java:699)
    at android.graphics.Canvas.native_drawOval(Canvas.java:-1)
    at android.graphics.Canvas.drawOval(Canvas.java:979)
    at org.codeandmagic.android.gauge.GaugeView.drawRim(GaugeView.java:630)
    at org.codeandmagic.android.gauge.GaugeView.drawGauge(GaugeView.java:592)
    at org.codeandmagic.android.gauge.GaugeView.onSizeChanged(GaugeView.java:576)
    at android.view.View.sizeChange(View.java:14400)
    at android.view.View.setFrame(View.java:14375)
    at android.view.View.layout(View.java:14286)
    at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1076)
    at android.view.View.layout(View.java:14289)
    at android.view.ViewGroup.layout(ViewGroup.java:4559)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
    at android.view.View.layout(View.java:14289)
    at android.view.ViewGroup.layout(ViewGroup.java:4559)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
    at android.view.View.layout(View.java:14289)
    at android.view.ViewGroup.layout(ViewGroup.java:4559)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
    at android.view.View.layout(View.java:14289)
    at android.view.ViewGroup.layout(ViewGroup.java:4559)

    ———–

    And when using this:

    I get this error:

    java.lang.NullPointerException
    at android.content.res.BridgeResources.getString(BridgeResources.java:501)
    at android.content.Context.getString(Context.java:334)
    at org.codeandmagic.android.gauge.GaugeView.readAttrs(GaugeView.java:224)
    at org.codeandmagic.android.gauge.GaugeView.(GaugeView.java:170)
    at org.codeandmagic.android.gauge.GaugeView.(GaugeView.java:175)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(NativeConstructorAccessorImpl.java:-2)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass(ProjectCallback.java:422)
    at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.loadView(ProjectCallback.java:179)
    at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:207)
    at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:135)
    at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:755)
    at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:727)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:373)

    Please help

    • NP

      Did you find already the issue on your problem? I just download and configured also this and mentioned the same issue;

      java.lang.ArrayIndexOutOfBoundsException: 3
      at android.graphics.Gradient_Delegate$GradientPaint.precomputeGradientColors(Gradient_Delegate.java:110)
      at

      Thanks in advance!

  • pzolee

    Hi,
    I am stuck a bit. Everything is fine, but when I try to open activity_main.xml it reports the next problem:
    java.lang.NullPointerException
    at android.content.res.BridgeResources.getString(BridgeResources.java:501)
    at android.content.Context.getString(Context.java:327)
    at org.codeandmagic.android.gauge.GaugeView.readAttrs(GaugeView.java:224)
    at org.codeandmagic.android.gauge.GaugeView.(GaugeView.java:170)
    at org.codeandmagic.android.gauge.GaugeView.(GaugeView.java:175)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0( at …

    Can you help me?

    • Or Kazaz

      I can’t get it to work and I get the same error.. Do you have any idea what is it??

      • http://www.ehartwell.com Eric Hartwell

        The textUnit attribute has to be a string reference, not a string. In activity_main.xml replace gauge:textUnit=”%” with gauge:textUnit=”@string/percent” and add %

  • LB

    Is it possible to have a start value from a negative number, let’s say scale start from -2 and ends at +2

    Thanks, anyone

  • Andrea

    After a bit of effort… it worked on API level 17!!! TNX Evelyne!!

  • Abdul

    Thank you for this great work!

    Could you please let me know if gauge_view2 can show numbers with decimal places?

  • mstulina

    This is great! Hope you’ll continue work on this project

  • JASX

    Thank you Evelina. You saved my time.

  • Edilson Mendes

    The problem occurs because the GaugeView always reads the values of the properties gauge:rangeValues and gauge:rangeColors from lib (limited to 100) and not the provided by the user application. To fix it on lib side, change the class GaugeView replacing the lines 238 e 238 with
    final String[] ranges = res.getStringArray(rangesId);
    final String[] colors = res.getStringArray(colorsId);

    To test it, on application side:
    1) Create two string arrays: one array with ranges that you wish change the colors and another array with color values itself (booths arrays must be the same size). Example:

    400
    800
    1200
    1800

    #E7202B
    #E86F21
    #E8E721
    #1BCA21

    2) On your layout file you must specify the follow attributes gauge:scaleStartValue, gauge:scaleEndValue, gauge:showRanges, gauge:rangeValues, gauge:rangeColors. In example below, my gauge shows the range between 0 and 1800 and the colors get changed from value 400, 800, 1200 and 1800 (see ranges and rangeColors arrays on step 1)

  • Michael Zarletti

    forbiddenera

    I’m still crashing when I set the SCALE_END_VALUE over 100. Was there any additional changes needed?

    Thanks much

  • Zio

    Small bug about ranges colors and values:

    private void readRanges(final Resources res, final int rangesId, final int colorsId) {
    if (rangesId > 0 && colorsId > 0) {
    final String[] ranges = res.getStringArray(rangesId); // instead of (R.array.ranges);
    final String[] colors = res.getStringArray(colorsId); // instead of (R.array.rangeColors);

    bye

  • forbiddenera

    sorry my ide is playing games with me, disregard the last post, code should be ok before that.. modulus on mDivisionValue. plz verify and edit/delete my silly comments.

  • forbiddenera

    oops in my code (its late) . should be:
    if (0 == value % mDivisions) {

    if that’s not perfect, I’m sorry. should be. I’m done tonight. cheers

  • forbiddenera

    ok.. I’ve got it working.. with this fix,divs is how many times it gets divided.and sub is how many.times a div.gets divided.. sorry about all the posts but this wassabug and I just spent all night tinkering it away cuz I wanna use this gauge, coding right on my phone.. gr is passed its 5am but here:

    private void initScale() {
    mScaleRotation = (mScaleStartAngle + 180) % 360;
    mDivisionValue = (mScaleEndValue – mScaleStartValue) / mDivisions;
    mSubdivisionValue = mDivisionValue / mSubdivisions;
    mSubdivisionAngle = (360 – 2 * mScaleStartAngle) / (mDivisions * mSubdivisions);
    }

    …….

    private void drawScale(final Canvas canvas) {
    canvas.save(Canvas.MATRIX_SAVE_FLAG);

    // On canvas, North is 0 degrees, East is 90 degrees, South is 180 etc.
    // We start the scale somewhere South-West so we need to first rotate the canvas.
    canvas.rotate(mScaleRotation, 0.5f, 0.5f);

    final int totalTicks = mDivisions * mSubdivisions;
    for (int i = 0; i < totalTicks+1; i++) {
    final float y1 = mScaleRect.top;
    final float y2 = y1 + 0.015f; // height of division
    final float y3 = y1 + 0.045f; // height of subdivision

    final float value = getValueForTick(i);
    final Paint paint = getRangePaint(value);
    if (0 == value % mDivisionValue) {
    // Draw a division tick
    canvas.drawLine(0.5f, y1, 0.5f, y3, paint);
    // Draw the text 0.15 away from the division tick
    canvas.drawText(valueString(value), 0.5f, y3 + 0.045f, paint);
    }
    else {
    // Draw a subdivision tick
    canvas.drawLine(0.5f, y1, 0.5f, y2, paint);
    }
    canvas.rotate(mSubdivisionAngle, 0.5f, 0.5f);
    }
    canvas.restore();
    }

    private String valueString(final float value) {
    return String.format("%d", (int) value);
    }

    private float getValueForTick(final int tick) {
    return tick * (mDivisionValue / mSubdivisions);
    }

  • forbiddenera

    even with that code. it’s not perfect. trying to have a max of 9500 or 9000 (rpm) .. works with my code at 10000 max. sorry, dunno where else to.post bugs

  • forbiddenera

    I’ve figured that all out.. seems to crash when the highest value of rangevalues isn’t the same as the end value.. also. subdivision isn’t working right? from what I can tell division is how far to put a tick (eg every x), sub division should be divided by that. but it wasn’t. missing line of code:

    if (0 == value % (mDivisions/mSubdivisions))

  • forbiddenera

    actually scaleEndValue != 100.0 it seems to crash.. still a noonb dunno where my errors are.

  • forbiddenera

    I am trying to set the scaleStartValue and.scaleEndValue via xml layput and it crashes.

  • rocks

    hi, get
    3 errors when i import the projetc in eclipse

    1- setContentView(R.layout.activity_main) layout cannot be resolved or is not a field

    2-mGaugeView1 = (GaugeView) findViewById(R.id.gauge_view1); id cannot be resolved or is not a field

    3-mGaugeView2 = (GaugeView) findViewById(R.id.gauge_view2); id cannot be resolved or is not a field

    thanks for helping

    • notif

      I think the problem is that you don’t upload the good ressource file in your activity.
      Make sure that you have(where is marked import) : import YOURPROJECTPACKAGE.R and not import android.R

      • Noal

        I have the same errors, but do not understand your explanation of the problem. I have the following:

        import org.codeandmagic.android.gauge.GaugeView;

        import org.codeandmagic.android.gauge.R;

        what should i have?

        • Noal

          nevermind, i got it to work. I deleted those 2 import lines, then hit ctrl+shift+o to reimport whatever was needed, and now it works.

  • kostas

    Thnaks it worked perfectly!!

  • notif

    Hi!
    Is it possible to change rangecolor? how can i do it?Thx

    • kostas

      You must change the colors in the GaugeView code…at 77 line i think ….

      public static final int[] RANGE_COLORS = { Color.WHITE, Color.WHITE,
      Color.WHITE };

      I made them all white…

      • notif

        Thanks for your answer. I’ ve changed the color in the other way. I’ ve just used an array file in my res folder and apply it in gauge: rangevalues.

  • http://www.facebook.com/nishu.khatri.96 Nishu Khatri

    Hi.. Thanks for sharing this library..

    I am getting error in xml as follows by using gaugeview-lbrary.jar in myproject:

    “Error inflating class org.codeandmagic.android.gauge.GaugeView”

    Can u please help me how to resolve it…

    Thanks in advance.

    • notif

      Hi!
      Is it possible to change rangecolor? how can i do it?Thx

    • Abhishek

      I too get the same error. can you please tell me how to resolve this error.

      • stump

        Clean the project before attempting to load it. Start by cleaning the library, then the samples. Check Project Preferences to ensure that it has the library referenced correctly

  • Sorin

    Awsome.Thx verry helpful. Thx for the neat code and explanations.Really helped.

  • Sanath Nandasiri

    cool..

  • julien quiévreux

    thank you for sharing

  • ThummyT

    The gitHub download doesn’t work

    • evelyne24

      It works for me. What are you getting back?