Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
290 views
in Technique[技术] by (71.8m points)

android - Animating and rotating an image in a Surface View

I would like to animate movement on a SurfaceView . Ideally I would like to also be notified once the animation had finished.

For example: I might have a car facing North. If I wanted to animate it so that it faces South for a duration of 500ms, how could I do that?

I am using a SurfaceView so all animation must be handled manually, I don't think I can use XML or the android Animator classes.

Also, I would like to know the best way to animate something continuously inside a SurfaceView (ie. a walk cycle)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Rotating images manually can be a bit of a pain, but here's how I've done it.

private void animateRotation(int degrees, float durationOfAnimation){
    long startTime = SystemClock.elapsedRealtime();
    long currentTime;
    float elapsedRatio = 0;
    Bitmap bufferBitmap = carBitmap;

    Matrix matrix = new Matrix();

    while (elapsedRatio < 1){
        matrix.setRotate(elapsedRatio * degrees);
        carBitmap = Bitmap.createBitmap(bufferBitmap, 0, 0, width, height, matrix, true);
        //draw your canvas here using whatever method you've defined
        currentTime = SystemClock.elapsedRealtime();
        elapsedRatio = (currentTime - startTime) / durationOfAnimation;
    }

    // As elapsed ratio will never exactly equal 1, you have to manually draw the last frame
    matrix = new Matrix();
    matrix.setRotate(degrees);
    carBitmap = Bitmap.createBitmap(bufferBitmap, 0, 0, width, height, matrix, true);
    // draw the canvas again here as before
    // And you can now set whatever other notification or action you wanted to do at the end of your animation

}

This will rotate your carBitmap to whatever angle you specify in the time specified + the time to draw the last frame. However, there is a catch. This rotates your carBitmap without adjusting its position on screen properly. Depending on how you're drawing your bitmaps, you could end up with your carBitmap rotating while the top-left corner of the bitmap stays in place. As the car rotates, the bitmap will stretch and adjust to fit the new car size, filling the gaps around it with transparent pixels. It's hard to describe how this would look, so here's an example rotating a square:

alt text

The grey area represents the full size of the bitmap, and is filled with transparent pixels. To solve this problem, you need to use trigonometry. It's a bit complicated... if this ends up being a problem for you (I don't know how you're drawing your bitmaps to the canvas so it might not be), and you can't work out the solution, let me know and I'll post up how I did it.

(I don't know if this is the most efficient way of doing it, but it works smoothly for me as long as the bitmap is less than 300x300 or so. Perhaps if someone knows of a better way, they could tell us!)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...