Hi,
I'm having trouble with using an animation on my Watch Face. Specifically, I've drawn a bunch of text and bitmaps through onUpdate, but at the start of a specific hour I would like the watch to only play a gif completely before showing everything else again. Based on the sample app example, as well as another I found, I had no issues with encoding and playing a gif on a real watch using the motion tool. However, the problem arises when I try to "transition" to an animation from a state where there are only bitmaps/text on the screen. As a simplified example, based on the sample app code I linked, this is what I'm doing:
// global vars private var _aniDone = false; var _aniInProg = false; ... function onUpdate(dc) { View.onUpdate(dc); hour = System.getClockTime().hour; //System.println(System.getClockTime().sec); // when the animation is done, kill it if (_aniDone == true && _aniInProg == true) // _aniInProg so we only run once { _aniDone = false; System.println("Done"); _animationDelegate.handleOnHide(self); WatchUi.requestUpdate(); } // play an animation at a particular time if (hour == 0) { if (_aniInProg != true) // run once { System.println("Animation starting"); _animationDelegate.handleOnShow(self); _animationDelegate.play(); WatchUi.requestUpdate(); _aniInProg = true; } } // stuff drawn on screen dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_TRANSPARENT); dc.drawText(100, 100, Graphics.FONT_NUMBER_MEDIUM, hour, Graphics.TEXT_JUSTIFY_CENTER); dc.clear(); }
with_aniDone set to true in the WatchUi.ANIMATION_EVENT_COMPLETE event. The code works fine on the simulator (I set the time to 11:59:55 pm and just wait out a few seconds), but on a real watch, the watch face will not play the animation unless I leave and then reenter the view. I am unable to transition "directly" to the animation playback, even with the Ui.requestUpdate() call. I've tried changing the logic a bit (e.g., checking the hour and then putting everything inside that condition) but the results are the same.
How can I fix this? Is my approach correct? This seems like it should be a fairly simple thing to resolve, and I haven't found any previous threads on it.
I'm including the AnimationController and AnimationDelegate codes below for completeness.
using Toybox.WatchUi; class DanceDanceAnimationController { private var _animation; private var _playing; function initialize() { _playing = false; } function handleOnShow(view) { if( view.getLayers() == null ) { // Initialize the Animation System.println("controller: initializing animation"); _animation = new WatchUi.AnimationLayer( Rez.Drawables.dark_hour, { :locX=>0, :locY=>0, } ); view.addLayer(_animation); } } function handleOnHide(view) { System.println("controller: Clearing animation"); view.clearLayers(); _animation = null; } function play() { if(!_playing) { System.println("controller: animation playing"); _animation.play({ :delegate => new DanceDanceAnimationDelegate(self) }); _playing = true; } } function stop() { if(_playing) { System.println("controller: animation stopping"); _animation.stop(); _playing = false; } } }
using Toybox.WatchUi; // This class bridges communication between the app and the animation // playback class DanceDanceAnimationDelegate extends WatchUi.AnimationDelegate { var _controller; // Constructor function initialize(controller) { AnimationDelegate.initialize(); _controller = controller; } // Animation event handler function onAnimationEvent(event, options) { switch(event) { case WatchUi.ANIMATION_EVENT_COMPLETE: _aniDone = true; case WatchUi.ANIMATION_EVENT_CANCELED: _controller.stop(); break; } } }