Top Banner

of 15

Animator Demo I

Apr 05, 2018

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
  • 7/31/2019 Animator Demo I

    1/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    Android Application Development Training Tutorial

    For more info visit

    http://www.zybotech.in

    http://www.zybotech.in/http://www.zybotech.in/http://www.zybotech.in/
  • 7/31/2019 Animator Demo I

    2/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    Info

    PR

    :0

    I:

    174

    L:

    8

    LD:

    27

    I:

    25

    Rank:

    12968

    Age:

    wait...

    I:

    0

    wh

    ois

    sou

    rceRobo:

    no

    Sitema

    p:no

    Rank:

    1662

    Price:

    168443Links:6|19 Density

    Previous |Next |Home

    Animator Demo I

    For many applications, particularly those that are scientific or educational in nature, it is important to be able to

    simulate precise motion of objects governed by mathematical equations. In this project we introduce the basics

    of how to use a Java thread to implement motion of objects on the screen governed by mathematical models.

    For an overview of graphics methods discussed here, see the AndroidGraphicsdocument.

    Methods for 2D Animation

    We have several options for 2D graphical animation in Android, varying in complexity and speed:

    1. The simplest but least powerful and least flexible option is to draw graphics or animations into a Viewobject from your layout. In this approach you only have to define the graphics that go into the View and

    the drawing (and possible simple animation) of your graphics can be handled by Android's normal Viewhierarchy drawing process. This method is only adequate for fixed images, or simple pre-defined

    animations. We won't discuss it further here, but for a basic introduction seeSimple Graphics inside a

    Viewand2D Graphics. For specific discussion of simple fixed animation that can be implemented in

    this way seeTween AnimationandFrame Animation.

    A tweened animation can perform a series of simple position, size, rotation, and

    transparency transformations on the contents of a View object. Aframe animation is a

    "traditional" animation in that is corresponds to displaying a sequence of related images

    ("flip-book animation"). Both of these kinds of animation can be implemented either in

    code or in XML resources, but often it is simplest to do it entirely within XML.

    2.

    3. For any animation that regularly needs to redraw itself a much better animation choice is to drawdirectly to a Canvas. Games, and the sort of scientific animation we are addressing here, are likely to

    fall into this category. ACanvasserves as an interface to the actual surface upon which your graphics

    will be drawn. It holds all of your draw calls, but display of the drawing is performed (through the

    agency of the Canvas) upon an underlyingBitmapthat is placed into the window by the system at the

    appropriate time. There are several ways to do this, differing primarily in whether the Canvas is

    http://%7B%7D/http://%7B%7D/http://toolbarqueries.google.com/search?client=navclient-auto&hl=en&ch=6472069289&ie=UTF-8&oe=UTF-8&features=Rank&q=info:http%3A%2F%2Feagle.phys.utk.edu%2Fguidry%2Fandroid%2FanimatorDemo.htmlhttp://toolbarqueries.google.com/search?client=navclient-auto&hl=en&ch=6472069289&ie=UTF-8&oe=UTF-8&features=Rank&q=info:http%3A%2F%2Feagle.phys.utk.edu%2Fguidry%2Fandroid%2FanimatorDemo.htmlhttp://toolbarqueries.google.com/search?client=navclient-auto&hl=en&ch=6472069289&ie=UTF-8&oe=UTF-8&features=Rank&q=info:http%3A%2F%2Feagle.phys.utk.edu%2Fguidry%2Fandroid%2FanimatorDemo.htmlhttp://www.google.com/search?hl=en&safe=off&q=site%3Aeagle.phys.utk.edu&btnG=Searchhttp://www.google.com/search?hl=en&safe=off&q=site%3Aeagle.phys.utk.edu&btnG=Searchhttp://siteexplorer.search.yahoo.com/advsearch?p=http%3A%2F%2Feagle.phys.utk.edu%2Fguidry%2Fandroid%2FanimatorDemo.html&bwm=i&bwmo=d&bwmf=uhttp://siteexplorer.search.yahoo.com/advsearch?p=http%3A%2F%2Feagle.phys.utk.edu%2Fguidry%2Fandroid%2FanimatorDemo.html&bwm=i&bwmo=d&bwmf=uhttp://siteexplorer.search.yahoo.com/advsearch?p=http%3A%2F%2Feagle.phys.utk.edu&bwm=i&bwmo=d&bwmf=shttp://siteexplorer.search.yahoo.com/advsearch?p=http%3A%2F%2Feagle.phys.utk.edu&bwm=i&bwmo=d&bwmf=shttp://www.bing.com/search?q=site%3Aeagle.phys.utk.edu&FORM=QBRE&mkt=en-UShttp://www.bing.com/search?q=site%3Aeagle.phys.utk.edu&FORM=QBRE&mkt=en-UShttp://www.alexa.com/siteinfo/eagle.phys.utk.eduhttp://www.alexa.com/siteinfo/eagle.phys.utk.eduhttp://%7B%7D/http://%7B%7D/http://delicious.com/url/993c6f3e4b97300c7ef5c726db49ab13http://delicious.com/url/993c6f3e4b97300c7ef5c726db49ab13http://www.whorush.com/search/?q=eagle.phys.utk.edu#whorushwhoishttp://www.whorush.com/search/?q=eagle.phys.utk.edu#whorushwhoishttp://www.whorush.com/search/?q=eagle.phys.utk.edu#whorushwhoishttp://eagle.phys.utk.edu/robots.txthttp://eagle.phys.utk.edu/robots.txthttp://eagle.phys.utk.edu/sitemap.xmlhttp://eagle.phys.utk.edu/sitemap.xmlhttp://eagle.phys.utk.edu/sitemap.xmlhttp://www.semrush.com/info/eagle.phys.utk.edu?ref=174537735http://www.semrush.com/info/eagle.phys.utk.edu?ref=174537735http://www.semrush.com/info/eagle.phys.utk.edu?ref=174537735http://www.semrush.com/info/eagle.phys.utk.edu?ref=174537735http://%7B%7D/http://%7B%7D/http://%7B%7D/http://%7B%7D/http://%7B%7D/http://%7B%7D/http://%7B%7D/http://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/animatorDemo2.htmlhttp://eagle.phys.utk.edu/guidry/android/animatorDemo2.htmlhttp://eagle.phys.utk.edu/guidry/android/animatorDemo2.htmlhttp://eagle.phys.utk.edu/guidry/android/index.htmlhttp://eagle.phys.utk.edu/guidry/android/index.htmlhttp://eagle.phys.utk.edu/guidry/android/index.htmlhttp://developer.android.com/guide/topics/graphics/index.htmlhttp://developer.android.com/guide/topics/graphics/index.htmlhttp://developer.android.com/guide/topics/graphics/index.htmlhttp://developer.android.com/guide/topics/graphics/index.html#draw-to-viewhttp://developer.android.com/guide/topics/graphics/index.html#draw-to-viewhttp://developer.android.com/guide/topics/graphics/index.html#draw-to-viewhttp://developer.android.com/guide/topics/graphics/index.html#draw-to-viewhttp://developer.android.com/guide/topics/graphics/2d-graphics.htmlhttp://developer.android.com/guide/topics/graphics/2d-graphics.htmlhttp://developer.android.com/guide/topics/graphics/2d-graphics.htmlhttp://developer.android.com/guide/topics/graphics/2d-graphics.html#tween-animationhttp://developer.android.com/guide/topics/graphics/2d-graphics.html#tween-animationhttp://developer.android.com/guide/topics/graphics/2d-graphics.html#tween-animationhttp://developer.android.com/guide/topics/graphics/2d-graphics.html#frame-animationhttp://developer.android.com/guide/topics/graphics/2d-graphics.html#frame-animationhttp://developer.android.com/guide/topics/graphics/2d-graphics.html#frame-animationhttp://developer.android.com/guide/topics/graphics/index.html#draw-with-canvashttp://developer.android.com/guide/topics/graphics/index.html#draw-with-canvashttp://developer.android.com/reference/android/graphics/Canvas.htmlhttp://developer.android.com/reference/android/graphics/Canvas.htmlhttp://developer.android.com/reference/android/graphics/Canvas.htmlhttp://developer.android.com/reference/android/graphics/Bitmap.htmlhttp://developer.android.com/reference/android/graphics/Bitmap.htmlhttp://developer.android.com/reference/android/graphics/Bitmap.htmlhttp://developer.android.com/reference/android/graphics/Bitmap.htmlhttp://developer.android.com/reference/android/graphics/Canvas.htmlhttp://developer.android.com/guide/topics/graphics/index.html#draw-with-canvashttp://developer.android.com/guide/topics/graphics/2d-graphics.html#frame-animationhttp://developer.android.com/guide/topics/graphics/2d-graphics.html#tween-animationhttp://developer.android.com/guide/topics/graphics/2d-graphics.htmlhttp://developer.android.com/guide/topics/graphics/index.html#draw-to-viewhttp://developer.android.com/guide/topics/graphics/index.html#draw-to-viewhttp://developer.android.com/guide/topics/graphics/index.htmlhttp://eagle.phys.utk.edu/guidry/android/index.htmlhttp://eagle.phys.utk.edu/guidry/android/animatorDemo2.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://%7B%7D/http://%7B%7D/http://%7B%7D/http://www.semrush.com/info/eagle.phys.utk.edu?ref=174537735http://www.semrush.com/info/eagle.phys.utk.edu?ref=174537735http://eagle.phys.utk.edu/sitemap.xmlhttp://eagle.phys.utk.edu/robots.txthttp://www.whorush.com/search/?q=eagle.phys.utk.edu#whorushwhoishttp://www.whorush.com/search/?q=eagle.phys.utk.edu#whorushwhoishttp://delicious.com/url/993c6f3e4b97300c7ef5c726db49ab13http://%7B%7D/http://www.alexa.com/siteinfo/eagle.phys.utk.eduhttp://www.bing.com/search?q=site%3Aeagle.phys.utk.edu&FORM=QBRE&mkt=en-UShttp://siteexplorer.search.yahoo.com/advsearch?p=http%3A%2F%2Feagle.phys.utk.edu&bwm=i&bwmo=d&bwmf=shttp://siteexplorer.search.yahoo.com/advsearch?p=http%3A%2F%2Feagle.phys.utk.edu%2Fguidry%2Fandroid%2FanimatorDemo.html&bwm=i&bwmo=d&bwmf=uhttp://www.google.com/search?hl=en&safe=off&q=site%3Aeagle.phys.utk.edu&btnG=Searchhttp://toolbarqueries.google.com/search?client=navclient-auto&hl=en&ch=6472069289&ie=UTF-8&oe=UTF-8&features=Rank&q=info:http%3A%2F%2Feagle.phys.utk.edu%2Fguidry%2Fandroid%2FanimatorDemo.htmlhttp://%7B%7D/
  • 7/31/2019 Animator Demo I

    3/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    obtained and managed by you or by the system, and whether the drawing operations take place on the

    main thread holding the View or on a separate thread.

    o The simplest way to implement this approach is to create a custom component by subclassingView and overriding itsonDraw(Canvas canvas)method to define your draws on the Canvas

    supplied with onDraw. Because these operations are all done on the same (UI) thread as your

    custom View component, you can then request a redraw directly with theinvalidate()method of

    View. (See the discussion of communication between threads in theProgress Bar Example

    project.) For animations that do not require much computing and need not be updated

    particularly rapidly, this may be an adequate approach. It was, for example, the method that we

    used in theDraggable Symbols IIproject to drag one symbol at a time about the stage.

    o The first option placed the redrawing and associated computation on the main UI thread. Thus itcould lead to non-responsiveness if the required computation becomes appreciable. A better

    alternative is to subclass View as above and to use the Canvas supplied and managed by Android

    through the onDraw(Canvas canvas) method for redraws, but to move the computation to a

    separate thread. Then, as discussed in theProgress Bar Example, we must deal with the issue

    that the second thread cannot call invalidate() directly on the UI-thread View. In that case, we

    must either define aHandleron the main UI thread to receive messages from the second thread

    and initiate invalidate(), or use the View methodpostInvalidate(), which is legal on a non-UI

    thread.

    We shall use the second method in the projectAnimator Demo 2. We used the first

    method in theProgress Bar Example, and it is also the method used in the Android

    Snakeexample code. (Snake is a motion game, but one that does not require a very high

    frame rate or complex redraws at each screen update.)

    o

    o The preceding two approaches have the advantage of relative simplicity since the Canvas usedfor drawing is supplied and managed by the system through the onDraw(Canvas canvas)

    method ofView. It has the disadvantage that the maximum speed of animation is restricted

    because it is dependent on a requestto the system to redraw the screen, which will be honored

    only when the system is ready to do so. A faster alternative is to move the animation to a

    separate thread that manages aSurfaceView(which provides a dedicated drawing surface

    embedded inside a view hierarchy), with access to the drawing surface typically implemented

    through theSurfaceHolderinterface, and perform draws as fast as the thread can execute (with

    no invalidate() calls). The disadvantage is that you must manage the drawing Canvas yourself,

    but the potential increase in speed makes this the preferred method for performance-intensive

    2D animation.

    http://developer.android.com/reference/android/view/View.html#onDraw%28android.graphics.Canvas%29http://developer.android.com/reference/android/view/View.html#onDraw%28android.graphics.Canvas%29http://developer.android.com/reference/android/view/View.html#onDraw%28android.graphics.Canvas%29http://developer.android.com/reference/android/view/View.html#invalidate%28%29http://developer.android.com/reference/android/view/View.html#invalidate%28%29http://developer.android.com/reference/android/view/View.html#invalidate%28%29http://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/dragSymbols.htmlhttp://eagle.phys.utk.edu/guidry/android/dragSymbols.htmlhttp://eagle.phys.utk.edu/guidry/android/dragSymbols.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://developer.android.com/reference/android/os/Handler.htmlhttp://developer.android.com/reference/android/os/Handler.htmlhttp://developer.android.com/reference/android/os/Handler.htmlhttp://developer.android.com/reference/android/view/View.html#postInvalidate%28%29http://developer.android.com/reference/android/view/View.html#postInvalidate%28%29http://developer.android.com/reference/android/view/View.html#postInvalidate%28%29http://eagle.phys.utk.edu/guidry/android/animatorDemo2.htmlhttp://eagle.phys.utk.edu/guidry/android/animatorDemo2.htmlhttp://eagle.phys.utk.edu/guidry/android/animatorDemo2.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://developer.android.com/resources/samples/Snake/index.htmlhttp://developer.android.com/resources/samples/Snake/index.htmlhttp://developer.android.com/reference/android/view/SurfaceView.htmlhttp://developer.android.com/reference/android/view/SurfaceView.htmlhttp://developer.android.com/reference/android/view/SurfaceView.htmlhttp://developer.android.com/reference/android/view/SurfaceHolder.htmlhttp://developer.android.com/reference/android/view/SurfaceHolder.htmlhttp://developer.android.com/reference/android/view/SurfaceHolder.htmlhttp://developer.android.com/reference/android/view/SurfaceHolder.htmlhttp://developer.android.com/reference/android/view/SurfaceView.htmlhttp://developer.android.com/resources/samples/Snake/index.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/animatorDemo2.htmlhttp://developer.android.com/reference/android/view/View.html#postInvalidate%28%29http://developer.android.com/reference/android/os/Handler.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/dragSymbols.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://developer.android.com/reference/android/view/View.html#invalidate%28%29http://developer.android.com/reference/android/view/View.html#onDraw%28android.graphics.Canvas%29
  • 7/31/2019 Animator Demo I

    4/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    Lunar LanderandJet Boyare examples of Android sample source code that use this

    latter approach by extendingSurfaceViewand implementing the

    SurfaceHolder.Callbackinterface. They are games that require faster screen redraws

    thanSnake.

    Let's now implement these ideas in some basic 2D animation. The example that we choose is to animate the

    motion of a planet around the Sun, assuming the planet to be in a circular orbit around a fixed Sun. The method

    that we shall use for this illustration is to implement the animation update on a dedicated thread and use

    postInvalidate() from that thread to force periodic screen updates.

    Creating the Initial ProjectCreate a new project in Eclipse with the following specification:

    Project name:AnimatorDemo

    Build Target:Android 2.2

    Application name:Animator Demo

    Package name: com.lightcone.animatordemo

    Create Activity:AnimatorDemo

    Min SDK Version: 3

    Thread Options

    As discussed in theProgress Bar Example, there are two basic ways to implement threading:

    1. Create a new class that extendsThreadand override itsrun()method.

    http://developer.android.com/resources/samples/LunarLander/index.htmlhttp://developer.android.com/resources/samples/LunarLander/index.htmlhttp://developer.android.com/resources/samples/JetBoy/index.htmlhttp://developer.android.com/resources/samples/JetBoy/index.htmlhttp://developer.android.com/resources/samples/JetBoy/index.htmlhttp://developer.android.com/reference/android/view/SurfaceView.htmlhttp://developer.android.com/reference/android/view/SurfaceView.htmlhttp://developer.android.com/reference/android/view/SurfaceView.htmlhttp://developer.android.com/reference/android/view/SurfaceHolder.Callback.htmlhttp://developer.android.com/reference/android/view/SurfaceHolder.Callback.htmlhttp://developer.android.com/resources/samples/Snake/index.htmlhttp://developer.android.com/resources/samples/Snake/index.htmlhttp://developer.android.com/resources/samples/Snake/index.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://developer.android.com/reference/java/lang/Thread.htmlhttp://developer.android.com/reference/java/lang/Thread.htmlhttp://developer.android.com/reference/java/lang/Thread.htmlhttp://developer.android.com/reference/java/lang/Thread.html#run%28%29http://developer.android.com/reference/java/lang/Thread.html#run%28%29http://developer.android.com/reference/java/lang/Thread.html#run%28%29http://developer.android.com/reference/java/lang/Thread.html#run%28%29http://developer.android.com/reference/java/lang/Thread.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://developer.android.com/resources/samples/Snake/index.htmlhttp://developer.android.com/reference/android/view/SurfaceHolder.Callback.htmlhttp://developer.android.com/reference/android/view/SurfaceView.htmlhttp://developer.android.com/resources/samples/JetBoy/index.htmlhttp://developer.android.com/resources/samples/LunarLander/index.html
  • 7/31/2019 Animator Demo I

    5/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    2. Provide a newThreadinstance with aRunnableobject using theRunnable interface during its creation.In theProgress Bar Examplewe used the first approach and created a new class extending Thread. In this

    example we shall use the second approach and implement thread-based animation by creating a class that

    implements theRunnableinterface.

    Implementing an Animation Thread Using Runnable

    Create a new public classMotionRunner.java, having it subclass View and implementRunnable: in Eclipse,

    File > New > Class, and then fill out the resulting screen as follows (substituting your namespace for

    com.lightcone)

    and clickFinish. OpenMotionRunner.java in the Eclipse editor, which should indicate an error: EclipseunderlinesMotionRunnerand hovering over it with the mouse gives the error message "Implicit super

    http://developer.android.com/reference/java/lang/Thread.htmlhttp://developer.android.com/reference/java/lang/Thread.htmlhttp://developer.android.com/reference/java/lang/Thread.htmlhttp://developer.android.com/reference/java/lang/Runnable.htmlhttp://developer.android.com/reference/java/lang/Runnable.htmlhttp://developer.android.com/reference/java/lang/Runnable.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://developer.android.com/reference/java/lang/Runnable.htmlhttp://developer.android.com/reference/java/lang/Runnable.htmlhttp://developer.android.com/reference/java/lang/Runnable.htmlhttp://developer.android.com/reference/java/lang/Runnable.htmlhttp://eagle.phys.utk.edu/guidry/android/progressBarExample.htmlhttp://developer.android.com/reference/java/lang/Runnable.htmlhttp://developer.android.com/reference/java/lang/Thread.html
  • 7/31/2019 Animator Demo I

    6/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    constructor View() is undefined for default constructor. Must define explicit constructor." Let Eclipse fix it by

    choosing "Add constructor 'MotionRunner(Context)'" from the options in the popup window. Then

    MotionRunner.java should read

    package com.lightcone.animatordemo;import android.content.Context;import android.view.View;

    public class MotionRunner extends View implements Runnable {

    public MotionRunner(Context context) {super(context);// TODO Auto-generated constructor stub

    }

    @Overridepublic void run() {

    // TODO Auto-generated method stub}

    }

    This should compile with no errors. Now editMotionRunner.java so that it reads

    package com.lightcone.animatordemo;

    import android.content.Context;import android.util.Log;

    import android.view.View;

    public class MotionRunner extends View implements Runnable {

    private Thread animator = null; // The thread that will hold the animationprivate long delay; // Delay in ms controlling speed of thread

    loopingprivate boolean please_stop = false; // Boolean controlling whether thread loop

    is running

    public MotionRunner(Context context) {super(context);

    }

    @Overridepublic void run() {

    while(!please_stop) {Log.i("ANIMATOR"," ..... LOOPED");// Wait then execute it againtry { Thread.sleep(delay); } catch (InterruptedException e) { ; }

    }}

    // Method to start animation looppublic void startIt(long delay) {

    this.delay = delay;animator = new Thread(this);animator.start();

    }

  • 7/31/2019 Animator Demo I

    7/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    // Method to stop animation looppublic void stopLooper(){

    please_stop = true;}

    // Method to resume animation loop

    public void startLooper(long delay){please_stop = false;if(animator == null) {

    startIt(delay);}

    }}

    where changes are highlighted in red. Let's describe briefly the functionality of this code.

    Because we have implemented theRunnableinterface, we are required to provide an implementation ofitsrun()method (which is called whenever a thread starts that has been created by the classimplementingRunnable). In this case run() will be invoked when theThreadcorresponding to the

    variable animatoris started.

    Within the run() method we implement a while-loop that will execute as long as the booleanplease_stop is false. For now we have just put a diagnostic output to the logcat stream to indicate that

    the thread is running. Later we will do more interesting things with this thread.

    The speed with which this loop executes is controlled by the long integer delay, since thesleep(longtime)method ofThreadrequests that the thread sleep for delay milliseconds each time through the

    while-loop (the delay is only a request and is not precise). Since the sleep(time) method throws the

    exceptionInterruptedException, it must be enclosed in a try-catch clause to handle the exception

    The method startIt(long delay) instantiates a Thread and starts it (which will cause the run() method tobe executed). The methods stopLooper() and startLooper(long delay) turn the while-loop in run() off

    and on by setting the value of the booleanplease_stop to true or false, respectively.

    Now we modifyAnimatorDemo.java to run the animation thread.

    Running the Animation Thread

    OpenAnimatorDemo.java in the Eclipse editor and modify it to read

    package com.lightcone.animatordemo;

    import android.app.Activity;

    http://developer.android.com/reference/java/lang/Runnable.htmlhttp://developer.android.com/reference/java/lang/Runnable.htmlhttp://developer.android.com/reference/java/lang/Runnable.htmlhttp://developer.android.com/reference/java/lang/Runnable.html#run%28%29http://developer.android.com/reference/java/lang/Runnable.html#run%28%29http://developer.android.com/reference/java/lang/Runnable.html#run%28%29http://developer.android.com/reference/java/lang/Thread.htmlhttp://developer.android.com/reference/java/lang/Thread.htmlhttp://developer.android.com/reference/java/lang/Thread.htmlhttp://developer.android.com/reference/java/lang/Thread.html#sleep%28long%29http://developer.android.com/reference/java/lang/Thread.html#sleep%28long%29http://developer.android.com/reference/java/lang/Thread.html#sleep%28long%29http://developer.android.com/reference/java/lang/Thread.html#sleep%28long%29http://developer.android.com/reference/java/lang/Thread.html#sleep%28long%29http://developer.android.com/reference/java/lang/Thread.html#sleep%28long%29http://developer.android.com/reference/java/lang/Thread.htmlhttp://developer.android.com/reference/java/lang/Runnable.html#run%28%29http://developer.android.com/reference/java/lang/Runnable.html
  • 7/31/2019 Animator Demo I

    8/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    import android.os.Bundle;import android.view.ViewGroup;

    public class AnimatorDemo extends Activity {

    private long delay = 40; // Delay in ms controlling speed of thread looping

    MotionRunner mrunner;

    /** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);// Instantiate the class MotionRunner to define the entry screen displaymrunner = new MotionRunner(this);mrunner.setLayoutParams(new

    ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.FILL_PARENT));

    setContentView(mrunner);mrunner.startIt(delay);

    }

    @Overridepublic void onPause() {

    super.onPause();// Stop animation loop if going into backgroundmrunner.stopLooper();

    }

    @Overridepublic void onResume() {

    super.onResume();// Resume animation loop

    mrunner.startLooper(delay);}

    }

    where changes are highlighted in red. This segment of code

    Defines an instance mrunnerof the classMotionRunnerthat we just created.

    Sets the content view for the entry screen to mrunnerusing the View method.setLayoutParamsand the

    Activity methodsetContentView.

    Executes the startIt(delay) method of theMotionRunnerinstance to start the animation.

    Defines onPause() and onResume() methods that pause and resume the animation by executing thestopLooper() and startLooper() methods, respectively, ofMotionRunnerwhen the app goes into and

    returns from the background.

    http://developer.android.com/reference/android/view/View.html#setLayoutParams%28android.view.ViewGroup.LayoutParams%29http://developer.android.com/reference/android/view/View.html#setLayoutParams%28android.view.ViewGroup.LayoutParams%29http://developer.android.com/reference/android/view/View.html#setLayoutParams%28android.view.ViewGroup.LayoutParams%29http://developer.android.com/reference/android/app/Activity.html#setContentView%28android.view.View%29http://developer.android.com/reference/android/app/Activity.html#setContentView%28android.view.View%29http://developer.android.com/reference/android/app/Activity.html#setContentView%28android.view.View%29http://developer.android.com/reference/android/app/Activity.html#setContentView%28android.view.View%29http://developer.android.com/reference/android/view/View.html#setLayoutParams%28android.view.ViewGroup.LayoutParams%29
  • 7/31/2019 Animator Demo I

    9/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    If you now execute this app on a phone or emulator you should see a blank screen (since we haven't told it to

    display anything yet), but in the logcat output there should be a sequence of "LOOPED" strings indicating that

    the while-loop in the thread is executing. By changing the value of the variable delay you should be able to

    approximately control how often this string is output. You also should find that the loop stops if you send the

    app to the background by hitting the back button or the home button.

    Adding Animated Motion

    We now have a basic animation thread running, so lets animate something with it by using the methods that

    mrunnerinherits from View to implement the motion of objects on the screen.

    Geometry of the Planetary Orbit

    The geometry that we shall assume for the planetary orbit is illustrated in the following figure,

    where we shall position the Sun at the center of the display screen and take it as the origin of the coordinate

    system. The animation will consist of moving the planet by a small increment on the circular orbit each timethrough the while-loop of the run()method, with the size of the increment controlled by the integersteps

    and the clockwise direction corresponding to positive increments. We implement this through the following

    additions and modifications.

    New Imports and Variables

    First, add the imports and new variables indicated in red in the following listing toMotionRunner.java.

  • 7/31/2019 Animator Demo I

    10/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    package com.lightcone.animatordemo;import android.content.Context;import android.util.Log;import android.view.View;

    import android.graphics.Canvas;

    import android.graphics.Color;import android.graphics.Paint;import android.graphics.drawable.ShapeDrawable;import android.graphics.drawable.shapes.OvalShape;

    public class MotionRunner extends View implements Runnable {private Thread animator = null; // The thread that will hold the

    animationprivate long delay; // Delay in ms controlling speed of

    thread loopingprivate boolean please_stop = false; // Boolean controlling whether

    thread loop is running

    static final int ORBIT_COLOR = Color.argb(255, 66, 66, 66);static final double RAD_CIRCLE = 2*Math.PI; // Number radians in a circleprivate Paint paint; // Paint object controlling format

    of screen drawsprivate ShapeDrawable planet; // Planet symbolprivate int planetRadius = 7; // Radius of spherical planet

    (pixels)private int sunRadius = 12; // Radius of Sun (pixels)private float X0 = 0; // X offset from center (pixels)private float Y0 = 0; // Y offset from center (pixels)private float X; // Current X position of planet

    (pixels)private float Y; // Current Y position of planet

    (pixels)private float centerX; // X for center of display

    (pixels)private float centerY; // Y for center of display

    (pixels)private float R0; // Radius of circular orbit

    (pixels)private int nsteps = 600; // Number animation steps around

    circleprivate double theta; // Angle around orbit (radians)private double dTheta; // Angular increment each step

    (radians)private double direction = -1; // Direction: counter-clockwise -

    1; clockwise +1

    where the purpose of each variable is defined in the comments.

    Setup and Initialization in the Constructor

    Next, add to the constructor ofMotionRunner.java the statements in red in the following listing.

  • 7/31/2019 Animator Demo I

    11/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    public MotionRunner(Context context) {super(context);// Initialize angle and angle step (in radians)theta = 0;dTheta = RAD_CIRCLE/((double) nsteps); // Angle increment in radians

    // Define the planet as circular shapeplanet = new ShapeDrawable(new OvalShape());planet.getPaint().setColor(Color.WHITE);planet.setBounds(0, 0, 2*planetRadius, 2*planetRadius);

    // Set up the Paint object that will control format of screen drawspaint = new Paint();paint.setAntiAlias(true);paint.setTextSize(14);paint.setStrokeWidth(1);

    }

    where the purpose of the statements should be clear from the comments and the documentation for the methods

    of the classesShapeDrawableandPaint.

    Getting the Device Screen Size

    Since we will need to know the display size of the view to calculate geometries, let's get the height and width of

    the full display. We do that by overriding the View methodonSizeChanged(int w, int h, int oldw, int oldh),

    adding toMotionRunner

    /*The View display size is only available after a certain stage of the layout. Before

    thenthe width and height are by default set to zero. The onSizeChanged method of View is

    calledwhen the size is changed and its arguments give the new and old dimensions. Thus

    this can beused to get the sizes of the View after it has been laid out (or if the layout

    changes, as in aswitch from portrait to landscape mode, for example).

    */

    @Overrideprotected void onSizeChanged (int w, int h, int oldw, int oldh){

    // Coordinates for center of screencenterX = w/2;centerY = h/2;// Make orbital radius a fraction of minimum of width and height of displayR0 = (float) (0.90*Math.min(centerX, centerY));// Set the initial position of the planet (translate by planetRadius so center of

    planet// is at this position)X = centerX - planetRadius ;

    Y = centerY - R0 - planetRadius;}

    http://developer.android.com/reference/android/graphics/drawable/ShapeDrawable.htmlhttp://developer.android.com/reference/android/graphics/drawable/ShapeDrawable.htmlhttp://developer.android.com/reference/android/graphics/drawable/ShapeDrawable.htmlhttp://developer.android.com/reference/android/graphics/Paint.htmlhttp://developer.android.com/reference/android/graphics/Paint.htmlhttp://developer.android.com/reference/android/graphics/Paint.htmlhttp://developer.android.com/reference/android/view/View.html#onSizeChanged%28int,%20int,%20int,%20int%29http://developer.android.com/reference/android/view/View.html#onSizeChanged%28int,%20int,%20int,%20int%29http://developer.android.com/reference/android/view/View.html#onSizeChanged%28int,%20int,%20int,%20int%29http://developer.android.com/reference/android/view/View.html#onSizeChanged%28int,%20int,%20int,%20int%29http://developer.android.com/reference/android/graphics/Paint.htmlhttp://developer.android.com/reference/android/graphics/drawable/ShapeDrawable.html
  • 7/31/2019 Animator Demo I

    12/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    You might wonder why we use this method to get the view height and width. Why not just call the View

    methodsgetWidth()andgetHeight()in the constructor, for example? Recall that we are generally using layouts

    that adapt to the device in use, so the geometry is known only at runtime. Furthermore, the screen geometry

    may change during execution if, for example, the phone is switched from portrait to landscape display by

    sliding out a keyboard.

    For these reasons, the getWidth() and getHeight() methods ofView will return zero if called too early(for example, within the constructor), because at that point Android doesn't yet know what the layout

    sizes will be.

    The view sizes are only available at some point in the layout phase as the app is executing.

    The protected methodonSizeChanged(int w, int h, int oldw, int oldh)ofView is executed by Androidwhen the sizes are changed, where the arguments w and h are the new width and height, and oldw and

    oldh are the old values.

    Thus, we can override this method to retrieve the width and height of the view as soon as they havebeen changed from their default values of zero. (Alternatively, we can retrieve the width and height

    after the layout phase; for example, within the while-loop of the run() method.)

    The qualifierprotectedrequired for the method onSizeChangedis an access-level

    modifier in Java (an alternative topublic,private, or the default package-level access if

    no qualifier is specified). A protected method is visible to all classes in the package and

    to classes outside the package that inherit the class. In writing your own classes, there

    are various (often strongly-held) views on declaring access levels. There is fairly

    common agreement that it is best to restrict access to methods and fields as much as

    possible. One approach to this is to

    1. Use theprivate modifier (not accessible in subclasses or other classes of thepackage) if the method or field is needed only within the class. Things thatshould not be changed if the class is subclassed should be declared private, for

    example.

    2. Use theprotectedmodifier (accessible in subclasses and other classes of thepackage) if there are cooperating classes within a single package that may need

    access to it, or you expect that the methods and variables of the class may be

    useful to someone extending the class.

    http://developer.android.com/reference/android/view/View.html#getWidth%28%29http://developer.android.com/reference/android/view/View.html#getWidth%28%29http://developer.android.com/reference/android/view/View.html#getWidth%28%29http://developer.android.com/reference/android/view/View.html#getHeight%28%29http://developer.android.com/reference/android/view/View.html#getHeight%28%29http://developer.android.com/reference/android/view/View.html#getHeight%28%29http://developer.android.com/reference/android/view/View.html#onSizeChanged%28int,%20int,%20int,%20int%29http://developer.android.com/reference/android/view/View.html#onSizeChanged%28int,%20int,%20int,%20int%29http://developer.android.com/reference/android/view/View.html#onSizeChanged%28int,%20int,%20int,%20int%29http://developer.android.com/reference/android/view/View.html#onSizeChanged%28int,%20int,%20int,%20int%29http://developer.android.com/reference/android/view/View.html#getHeight%28%29http://developer.android.com/reference/android/view/View.html#getWidth%28%29
  • 7/31/2019 Animator Demo I

    13/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    3. Otherwise use thepublic modifier (accessible by all classes) for methods andfields that may be of direct interest to uers of the class.

    The preceding considerations are motivated primarily by principles of good object-

    oriented design. However, note that in Java generally, and Android in particular, there

    also may be some performance issues associated with choice of access qualifiers, as

    described inDesigning for Performance. Of course we have no choice in this particular

    example: onSizeChangedis an Android method that must be declaredprotectedor it

    won't compile.

    Method to Increment the Angle and Compute New Position Coordinates

    Next we add a method newXY()that will increment and compute the corresponding screen coordinatesXand

    Yfor the planet. Add toMotionRunner.java the following code:

    // Method to increment theta and compute the new X and Y .private void newXY(){

    theta += dTheta;if(theta > RAD_CIRCLE) theta -= RAD_CIRCLE; // For convenience, keep angle 0-2piX = (float)(R0*Math.sin(direction*theta)) + centerX - planetRadius;

    Y = centerY - (float)(R0*Math.cos(direction*theta)) - planetRadius;Log.i("ANIMATOR", "X="+X+" Y="+Y);}

    Notice the use of the variable direction to control whether the motion is clockwise or counterclockwise, and

    that for convenience we have implemented some logic so that at any time in the animation the angle (which is

    specified in radians in the calculation, since the trigonometric methods expect radians for the angles) lies in the

    interval 0 to 2

    Modifications of therun() Method

    Now we modify run() to invoke the newXY() method that increments the position of the planet. The required

    changes are indicated in red in the following listing.

    @Overridepublic void run() {

    while(!please_stop) {// Move planet by dTheta and compute new X and YnewXY();

    // Must use postInvalidate() rather than invalidate() to request redraw since// this is invoked from different thread than the one that created the ViewpostInvalidate();// Wait, then execute it again

    http://developer.android.com/guide/practices/design/performance.htmlhttp://developer.android.com/guide/practices/design/performance.htmlhttp://developer.android.com/guide/practices/design/performance.htmlhttp://developer.android.com/guide/practices/design/performance.html
  • 7/31/2019 Animator Demo I

    14/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    try { Thread.sleep(delay); } catch (InterruptedException e) { ; }}

    }

    Note that the View methodpostInvalidate(), which causes the invalidate to happen on a subsequent cyclethrough the event loop, must be used rather than invalidate() to request a redraw from a thread other than the

    one that created the View (see the discussion above and in the AndroidGraphicsdocument).

    Overriding theonDraw(Canvas canvas) Method

    Finally, we override theonDraw(Canvas canvas)method inherited from View to reflect the updated position of

    the planet when the screen is redrawn in response to thepostInvalidate() request in run(). To do so, add the

    following two methods toMotionRunner.java.

    /*This method will be called each time the screen is redrawn. The draw ison the Canvas object, with formatting controlled by the Paint object.When to redraw is under Android control, but we can request a redrawusing the method invalidate() or postInvalidate() inherited from the View superclass.In this case we must use postInvalidate(), since we are updating on a thread separatefrom the main UI thread.*/

    @Overridepublic void onDraw(Canvas canvas) {

    super.onDraw(canvas);drawBackground(paint, canvas);canvas.save();canvas.translate(X + X0, Y + Y0);planet.draw(canvas);canvas.restore();

    }

    // Called by onDraw to draw the backgroundprivate void drawBackground(Paint paint, Canvas canvas){

    paint.setColor(Color.YELLOW);paint.setStyle(Paint.Style.FILL);canvas.drawCircle(centerX + X0, centerY + Y0, sunRadius, paint);

    paint.setStyle(Paint.Style.STROKE);paint.setColor(ORBIT_COLOR);canvas.drawCircle(centerX + X0, centerY + Y0, R0, paint);

    }

    The techniques used here are documented under the methods for the Android classesCanvas,Paint, andColor,

    and are similar to those already discussed in conjunction with the onDraw method in theDraggableSymbols

    project. Notice that the Canvas on which were are drawing is supplied to us as the argument canvas, so we

    don't have to manage the Canvas; we only have to draw on it. The formatting of our drawing is controlled by

    the Paintobjectpaintthat we initialized in theMotionRunnerconstructor.

    http://developer.android.com/reference/android/view/View.html#postInvalidate%28%29http://developer.android.com/reference/android/view/View.html#postInvalidate%28%29http://developer.android.com/reference/android/view/View.html#postInvalidate%28%29http://developer.android.com/guide/topics/graphics/index.htmlhttp://developer.android.com/guide/topics/graphics/index.htmlhttp://developer.android.com/guide/topics/graphics/index.htmlhttp://developer.android.com/reference/android/view/View.html#onDraw%28android.graphics.Canvas%29http://developer.android.com/reference/android/view/View.html#onDraw%28android.graphics.Canvas%29http://developer.android.com/reference/android/view/View.html#onDraw%28android.graphics.Canvas%29http://developer.android.com/reference/android/graphics/Canvas.htmlhttp://developer.android.com/reference/android/graphics/Canvas.htmlhttp://developer.android.com/reference/android/graphics/Canvas.htmlhttp://developer.android.com/reference/android/graphics/Paint.htmlhttp://developer.android.com/reference/android/graphics/Paint.htmlhttp://developer.android.com/reference/android/graphics/Paint.htmlhttp://developer.android.com/reference/android/graphics/Color.htmlhttp://developer.android.com/reference/android/graphics/Color.htmlhttp://developer.android.com/reference/android/graphics/Color.htmlhttp://eagle.phys.utk.edu/guidry/android/DraggableSymbols.htmlhttp://eagle.phys.utk.edu/guidry/android/DraggableSymbols.htmlhttp://eagle.phys.utk.edu/guidry/android/DraggableSymbols.htmlhttp://eagle.phys.utk.edu/guidry/android/DraggableSymbols.htmlhttp://developer.android.com/reference/android/graphics/Color.htmlhttp://developer.android.com/reference/android/graphics/Paint.htmlhttp://developer.android.com/reference/android/graphics/Canvas.htmlhttp://developer.android.com/reference/android/view/View.html#onDraw%28android.graphics.Canvas%29http://developer.android.com/guide/topics/graphics/index.htmlhttp://developer.android.com/reference/android/view/View.html#postInvalidate%28%29
  • 7/31/2019 Animator Demo I

    15/15

    A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

    Run Planet, Run!

    If you now compile this code and run it on an emulator or phone you should see the planet moving around the

    Sun in a circle, as in the following figure (a screenshot taken on a Samsung Galaxy S phone in horizontal

    mode).

    If you look at the logcat output you should see a steady stream ofXand Yposition updates because of theLog.i() statement that we inserted, and if you hit the back or home buttons the screen animation and this stream

    of position updates should halt, indicating that the onPause() method ofAnimatorDemo has stopped execution

    of the update thread by invoking the stopLooper() method ofMotionRunner.

    With the integer direction set to -1, the motion is counterclockwise; change it to +1 to

    give clockwise motion. The speed and smoothness of the animation are controlled by

    the parameters nsteps, which specifies the number of animation steps to take each time

    around the circle, and delay, which specifies the delay in milliseconds for each

    animation step.

    The complete project for the application described above is archived at the linkAnimatorDemo.

    http://eagle.phys.utk.edu/guidry/android/projects/AnimatorDemo.tar.gzhttp://eagle.phys.utk.edu/guidry/android/projects/AnimatorDemo.tar.gzhttp://eagle.phys.utk.edu/guidry/android/projects/AnimatorDemo.tar.gzhttp://eagle.phys.utk.edu/guidry/android/projects/AnimatorDemo.tar.gz