Problem trying to stop an animation

Hi all,

I am writing here because I am trying to show an animation with the help of the Animation Watchface example when an activity is started or recorded and make it disappear when finished, similar to the native apps of the watch. So far, I am able to show the animation, but I am having issues trying to stop it and set visibility to false.

class AnimationDelegate extends WatchUi.AnimationDelegate {

    private var _view;

    //! Constructor
    //! @param view The watch face view
    public function initialize(view) {
        _view = view;
        WatchUi.AnimationDelegate.initialize();
    }

    //! Handle an animation event
    //! @param event The animation event
    //! @param options A dictionary of animation options
    public function onAnimationEvent(event as AnimationEvent, options as Dictionary) as Void {
    	System.println("I am on function onAnimationEvent");
        if (event == WatchUi.ANIMATION_EVENT_COMPLETE) {
        	_view.stop(); -> This is my problematic line
        	_view.setVisible(false);
        } else if (event == WatchUi.ANIMATION_EVENT_CANCELED) {
            _view.stop();
        } else {
            System.println("on unknown event");
        }
    }
}

class Marcador_tenis_padel_activityView extends WatchUi.View {

	//Declaration of variables
    
	function initialize() {
        View.initialize();
        
        _foregroundAnimationLayer = new WatchUi.AnimationLayer(animResource, null);
    }

    // Load your resources here
    function onLayout(dc as Dc) as Void {
        setLayout(Rez.Layouts.MainLayout(dc));
        System.println("Setting layout as I am on function onLayout!");
        
        addLayer(_foregroundAnimationLayer);
    }

	//! Play the animation
    public function play() as Void {
        	_foregroundAnimationLayer.setVisible(true);
            var animationRez = _foregroundAnimationLayer.getResource();
            var x = 0;
            var y = 0;
            // reset the x and z (layer) to the new coordinates
            _foregroundAnimationLayer.setLocation(x, y);
            // start the playback
            _foregroundAnimationLayer.play({:delegate=>new $.AnimationDelegate(self)});
        }
    }
    
    function onHide() as Void {
    	if($.showingMainMenu == false)
        {
        	if(_foregroundAnimationLayer != null)
	        {
	        	play();
	        }
        }
    }

My problem comes with the line which says _view.stop(), as the app crashes saying "\nError: Symbol Not Found Error\nDetails: Could not find symbol 'stop'\nStack: \n  - onAnimationEvent()...". Any idea of the cause of error?

Thanks,

Javier

  • there's no method stop in Marcador_tenis_padel_activityView or View

  • I think you need to call stop() on the animation object, not the view object, as in:

    https://forums.garmin.com/developer/connect-iq/b/news-announcements/posts/bring-your-app-to-life-with-animation

    In this case, I think you can fix this by implementing a stop() method in your view (Marcador_tenis_padel_activityView), similar to the play() method.

    e.g.

    public function stop() {
      _foregroundAnimationLayer.stop();
    }

  • Many thanks to both of you. Reviewing the both examples, the one I mentioned and the one on the link that also had a look at, I implemented the stop() function and the problem was solved.

    Now there is another issue I would like to ask about. Why is it that the animation is still displayed despite of the following?

    function stop() as Void {
    	System.println("I am on function stop()");
    	_foregroundAnimationLayer.stop();
        _foregroundAnimationLayer.setVisible(false);
        removeLayer(_foregroundAnimationLayer);
    }

  • how did you start/show the animation?

  • The animation starts from the onHide function when a menuItem is selected from a menu. So far, it starts the animation when I expect:

    class Marcador_tenis_padel_activityView extends WatchUi.View {
    	var _foregroundAnimationLayer as AnimationLayer;
    	private var animResource;
    	
    	function initialize() {
            View.initialize();
            
            //some code not relevant for this question
            
            animResource = $.Rez.Drawables.playIcon;
            _foregroundAnimationLayer = new WatchUi.AnimationLayer(animResource, null);
    	}
    
        function onLayout(dc as Dc) as Void {
            setLayout(Rez.Layouts.MainLayout(dc));
            addLayer(_foregroundAnimationLayer);
        }	
        
        function onHide() as Void {
        	System.println("I am on onHide() function");
        	if($.showingMainMenu == false) //Used to check if I am exiting from the menu which item selection makes the animation to be shown
            {
            	if(_foregroundAnimationLayer != null)
    	        {
    	        	if($.animationCanBeStopped == false)
    	        	{
    		        	play(); //This function is called when I expect
    		        }
    	        }
    	        else
    	        {
    	        	System.println("_foregroundAnimationLayer IS null!");
    	        }
            }
    }

  • this doesn't look like a menu, but rather than the view. Starting it onHide seems counterintuitive. Nevertheless if you say it works, then let it be. But you haven't show us the play(). Where is the animation? Is it on another view that is in a layer below Marcador_tenis_padel_activityView?

  • After reviewing again my code and agreeing that calling play() from onHide is not very intuitive, I made a small change and now I call it from onShow(), and with the latest changes I could see that now it works as expected. In order to answer to your question and to help others that may struggle as well, here I write what I did.

    The animation is defined at the view, more concretely at the initialize function:

    class Marcador_tenis_padel_activityView extends WatchUi.View {
    
    	var _foregroundPlayAnimationLayer as AnimationLayer;
    			
    	private var _drawLayer as Layer;
    	private var _drawLayerArea as Array<Number>;
    
        private var _partialUpdateClip as Array<Number>;
    
        private var _majorTextOffsetX as Number;
        private var _majorTextOffsetY as Number;
    
        private var _minorTextOffsetX as Number;
        private var _minorTextOffsetY as Number;
    
        private const MAJOR_FONT = Graphics.FONT_NUMBER_MEDIUM;
        private const MINOR_FONT = Graphics.FONT_NUMBER_MILD;
        private const GAP = 10;
        
    	function initialize() {
            View.initialize();
            
            _foregroundPlayAnimationLayer = new WatchUi.AnimationLayer($.Rez.Drawables.playIcon, null); //Here is the AnimationLayer initialised
        }
    }
    
        // Load your resources here
        function onLayout(dc as Dc) as Void {
            setLayout(Rez.Layouts.MainLayout(dc));
            
            addLayer(_foregroundPlayAnimationLayer);    //Add Layer for animation   
        }
    
        // Called when this View is brought to the foreground. Restore
        // the state of this View and prepare it to be shown. This includes
        // loading resources into memory.
        function onShow() as Void {
        	System.println("I am on function onShow()!");
        	System.println("$.exitingMenu: " + $.exitingMenu);
        	if($.exitingMenu == false)
        	{
        		//Some code which is not relevant for this post
    		}
    		else
    		{	
    			if($.showAnimation == true) //Called if the menu where the selected option will provoke the animation to be played
    	        {
            		play();
            		$.showAnimation = false;
    	        }
    		}
        }
    
    
    	//! Play the animation
        public function play() as Void {
        		System.println("I am on play() function");
                System.println("$.iconToShow: " + $.iconToShow);
                if($.iconToShow != null)
                {
                	//_foregroundPlayAnimationLayer = new WatchUi.AnimationLayer($.Rez.Drawables.playIcon, null);
    	            switch($.iconToShow)
    	            {
    	            	case "play":
    	            	{
    	            		_foregroundPlayAnimationLayer.setVisible(true);
    	            		_foregroundPlayAnimationLayer.play({:delegate=>new $.AnimationDelegate(self)});
    	            		break;
    	            	}
    	            	//To be added other cases
    	            }
    	            var x = 0;
    	            var y = 0;
    	            System.println("Playback started!");
            	}
        }
        
        function stop() as Void {
    	    	System.println("I am on function stop()");
    	    	_foregroundPlayAnimationLayer.stop();
    		    _foregroundPlayAnimationLayer.setVisible(false);
    		    WatchUi.requestUpdate();
        }

    There is an additional question I have. Depending on the selected menu option, I would like to play a different animation. Is it a way to just change the animation resource, or should I create additional objects similar to _foregroundPlayAnimationLayer and associate the resource?