Android Gauge Animation Question
Asked Answered
S

2

11

Okay so i've been trying to do this for a couple of days and i am getting no where. So i have the following two images:

The First is a RPM Gauge

RPM Gauge

The Second image is a full white graphic representing rpm gauge being full:

Full Gauge

I want to do the following:

  1. ask the user for an RPM input, if for example they enter 1.2 the gauge will fill up as follows:

output

I have the user input working i need help with the animation. Here is what i have tried:

  1. I have tried using PorterDuff but it also clips the gauge in the background not just the white bar
  2. I've tried splitting the image into little bitmaps and store them into arrays so that i can recall parts but this was slow and often crashed
  3. I made some progress by applying the Gauge first to the canvas then saving the canvas: canvas.save(); then clipping a path on the white image then restoring the canvas. However i do not know how to clip in a circular fashion starting from bottom left to a 180 degress to the bottom right (CW). Is this the best way?

I know there is probably an easier or more efficient way of doing this i just don't have a clue. Anyone with any good ideas?

*Note all images are PNG's

Thanks in advance!

Shoddy answered 27/5, 2011 at 19:11 Comment(0)
S
9

As you already found, i would use clip:

  • draw background image
  • set clip
  • draw foreground image

I would use

Canvas.clipPath()

with path looking like pie slice starting in the center of circle, like this:

Clip path

To create clip path use something like:

public class PieView extends View {

    private int width = 200;
    private int angleStart = 135;
    private int sweep = 270;

    private Path p;

    private Paint paint = new Paint();

    public PieView(Context context, AttributeSet attrs) {
    super(context, attrs);
        p = new Path();
        //move into center of the circle
        p.setLastPoint(width/2, width/2);
        //add line from the center to arc at specified angle
        p.lineTo(width/2+(float)Math.cos(Math.toRadians(angleStart))*(width/2), 
                 width/2+(float)Math.sin(Math.toRadians(angleStart))*(width/2));
        //add arc from start angle with specified sweep
        p.addArc(new RectF(0, 0, width, width), angleStart, sweep);
        //from end of arc return to the center of circle
        p.lineTo(width/2, width/2);

        paint.setColor(Color.RED);
        paint.setStrokeWidth(1);
        paint.setStyle(Style.STROKE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(0,0,width,width, paint);
        canvas.drawPath(p,paint);
    }
}
Smallpox answered 27/5, 2011 at 19:35 Comment(7)
okay i will give that a shot. How would i make it look animated though? like it was filling up?Shoddy
implement some loop and change clipping accordinglySmallpox
i'm a little confused on the clipping part. Okay so there is a rectangle that is the bounding box of the gauge the rectangle is at: RectF bounds = new RectF (0,0,200,200); and i want to do a clip.addArc(bouns,start angle, sweep angle); im assuming, what would my start and sweep angle be? ive tried 180 to 0 but doesn't seem to produce the correct image.Shoddy
i have created some sample view to demonstrate use of the pathSmallpox
So a question regarding animation i put it in a for loop as follows: for (int i=0; i<185; i++){ p.addArc(new RectF(0,0,width,width), angleStart, i); p.lineTo(width/2, width/2); c.drawPath(p,cPaint); } but it only shows the last image (when i=185) also it take a long time to get there (really slow) is there a way to show this animation in a efficient and fast way?Shoddy
i'm assuming i have to invalidate() somewhereShoddy
Yes, you should call invalidate() somewhere to repaint the view. Regarding animation i'm not sure how to implement it the best way.Smallpox
A
1

This is how to draw arcs, from Android ApiDemos: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.html

Then you need to use xfermode to remove a part of the top image by using a canvas derived from a bitmap. You can see one example of this approach here: Make certain area of bitmap transparent on touch

Astraea answered 27/5, 2011 at 23:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.