ConnectIQ WatchFace help... just want to add a simple PNG to layout!

Former Member
Former Member
So my steps I did so far to add a simple png as the background of my watchface:

1. I added a few png's under resources/drawables/images (only trying to add just one of them for now)

2. Under resources/drawables/drawables.xml I added:
<drawables>
<bitmap id="LauncherIcon" filename="launcher_icon.png" />
<bitmap id="MiddleMonkeyPNG" filename="images/middlemonkey.png" />
</drawables>


3. Under resources/layouts/layout.xml, I added the bitmap id so it should draw it be4 the label:
<layout id="TwelveMonkeysWatchFace">
<drawable id="MiddleMonkeyPNG" />
<label id="TimeLabel" x="center" y="center" font="Gfx.FONT_LARGE" justification="Gfx.TEXT_JUSTIFY_CENTER" color="Gfx.COLOR_BLUE" />
</layout>


4. I wasn't sure if thats all that is needed to just add a bitmap to the layout... I still get the error below.
but I also tried to manually add it via onLayout(), like so as I wasn't sure if this is a needed step:

function onLayout(dc) {
var image = Ui.loadResource( Rez.Drawables.MiddleMonkeyPNG );
dc.drawBitmap( 0, 0, image );

setLayout(Rez.Layouts.TwelveMonkeysWatchFace(dc));
}




Seems valid, but I'm getting this error:

#############
...
Copying file.... 95% complete
Copying file.... 97% complete
Copying file.... 100% complete
File pushed successfully
Connection Finished
Closing shell and port
Found Transport: tcp
Connecting...
Connecting to device...
Device Version 0.1.0
Device id 1 name "A garmin device"
Shell Version 0.1.0
Failed invoking <symbol>
UnexpectedTypeException: Expected Class definition, given Number
TwelveMonkeysWatchFace in Rez:25
onLayout in C:\dev\workspace\eclipse-luna-workspace\my-watchface\source\monkwatchfaceView.mc:27
Unhandled Exception
Connection Finished
Closing shell and port
#############

Line 27 is the: setLayout(Rez.Layouts.TwelveMonkeysWatchFace(dc));
  • I also tried to manually add it via onLayout(), like so as I wasn't sure if this is a needed step:

    function onLayout(dc) {
    var image = Ui.loadResource( Rez.Drawables.MiddleMonkeyPNG );
    dc.drawBitmap( 0, 0, image );

    setLayout(Rez.Layouts.TwelveMonkeysWatchFace(dc));
    }


    You can remove those two lines. They are trying to draw the bitmap when the layout is being loaded. You should only do drawing from onUpdate().

    Shell Version 0.1.0
    Failed invoking <symbol>
    UnexpectedTypeException: Expected Class definition, given Number
    TwelveMonkeysWatchFace in Rez:25
    onLayout in C:\dev\workspace\eclipse-luna-workspace\my-watchface\source\monkwatchfaceView.mc:27
    Unhandled Exception

    Given the error message, it sounds a bit like there may be some constant that has the same name. Have you tried renaming your layout?

    Travis
  • You can remove those two lines. They are trying to draw the bitmap when the layout is being loaded. You should only do drawing from onUpdate().


    Given the error message, it sounds a bit like there may be some constant that has the same name. Have you tried renaming your layout?

    Travis


    The issue is that you have the background image listed in the <drawables> and within the <layout>. The layout is expecting you to define an actual bitmap, not reference an existing one like that.

    To fix the problem, get rid of the <drawable> tag from your layout and then move the <bitmap> tag to the layout.

    Cheers,
    Douglas
  • Former Member
    Former Member over 8 years ago
    Thanks!

    The issue is that you have the background image listed in the <drawables> and within the <layout>. The layout is expecting you to define an actual bitmap, not reference an existing one like that.

    To fix the problem, get rid of the <drawable> tag from your layout and then move the <bitmap> tag to the layout.

    Cheers,
    Douglas


    Thanks Douglas, thats exactly what it was! ... I moved the bitmap to layout and works now...
    Guess the ordering of how the .xml files are loaded makes a difference so thats why I couldnt do that.
    <layout id="TwelveMonkeysWatchFace">
    <label id="TimeLabel" x="center" y="center" font="Gfx.FONT_LARGE" justification="Gfx.TEXT_JUSTIFY_CENTER" color="Gfx.COLOR_BLUE" />
    <bitmap id="MiddleMonkeyPNG" filename="images/army-rect-watch-face.png"/>
    </layout>


    What should you put in that drawables.xml? I thought maybe it was there to keep all your drawables so you can reference them later in layout but guess I was wrong :).
    Is it there so you can use them in your java code and add bitmaps via that?
  • You can put drawable-list objects, the app icon, and bitmaps that you will load at runtime (outside of a layout) in there.
  • Former Member
    Former Member over 8 years ago
    You can put drawable-list objects, the app icon, and bitmaps that you will load at runtime (outside of a layout) in there.



    Hey TRAVIS.VITEK,
    Quick question related to your last comment in regards to putting resources/bitmaps that you want to load at runtime (dynamically) ...

    So I have a small png of a 'heart' that I would like to dynamically put into my watchface based on if the user wants to see the Heart Rate (I already implemented a setting for this).

    Currently the bitmap reference exists in drawables.xml (and not layout.xml so its not placed when you start up the app automatically... My MonkeyC onUpdate() code has to figure out whether to place it or not)


    <drawables>
    <bitmap id="LauncherIcon" filename="launcher_icon.png" />
    <bitmap id="HeartPNG" x="center" y="143" filename="images/heart.png"/>
    </drawables>


    I can't seem to figure out how to dynamically add this to the page though?
    I get this error with the below code:

    "Failed invoking <symbol>
    UnexpectedTypeException: Expected Class definition, given Number
    onUpdate in line ... 143
    Unhandled Exception"

    function onUpdate(dc) {
    ...
    var setting_ShowHeartRatePNG = Application.getApp().getProperty("ShowHeartRatePNG ")
    if( setting_ShowHeartRatePNG ) {
    var heartPNG = new Rez.Drawables.HeartPNG();
    dc.draw(heartPNG);
    }
    ...
    ...
    View.onUpdate(dc);
    }//onUpdate
  • Former Member
    Former Member over 8 years ago
    In regards to my last question, I got slightly further...
    I replace this code:
    var heartPNG = new Rez.Drawables.HeartPNG();
    dc.draw(heartPNG);


    with this:

    var heartPNG = Ui.loadResource(Rez.Drawables.HeartPNG);
    dc.drawBitmap( 100, 143, heartPNG);


    It doesn't give an error anymore... but it also doesnt show the 'heart' png on the screen either :).
    Any idea why it doesn't show up?


    I also tried moving it under onLayout(dc) to no avail..

    class monkwatchfaceView extends Ui.WatchFace {
    var heartPNG;
    // Load your resources here
    function onLayout(dc) {
    heartPNG = Ui.loadResource(Rez.Drawables.HeartPNG);
  • Former Member
    Former Member over 8 years ago
    thought I'd just bump this...
    I basically want to know how to dynamically display a bitmap in a drawables.xml. I can't seem to load it based on a setting.
  • Former Member
    Former Member over 8 years ago
    just a quick update... getting closer... after looking at a few examples... i see they all are doing what im doing in onLayout() [loading the Rez.Drawables item with Ui.loadResource() ] and same thing Im doing in onUpdate() [adding the bitmap via dc.drawBitmap(50, 50, heartRateIcon);].

    I did notice Eclipse automatically adds to the project View.onUpdate(dc); to the end of onUpdate().

    If i remove this, i see my icon! However everything else is removed? (all the labels and previous bitmaps). How can I have both my dynamically added bitmap... and my current labels/bitmaps both show up is the next question?

    I'll research now View.onUpdate(dc); maybe there's something im missing.



    class monkwatchfaceView extends Ui.WatchFace {
    var heartRateIcon;

    function initialize() {
    WatchFace.initialize();
    }

    // Load your resources here
    function onLayout(dc) {
    heartRateIcon = Ui.loadResource(Rez.Drawables.HeartRateIcon);

    setLayout(Rez.Layouts.TwelveMonkeysWatchFace(dc));
    }

    function onUpdate(dc) {
    ...
    var setting_ShowHeartRatePNG = Application.getApp().getProperty("ShowHeartRatePNG ")
    if( setting_ShowHeartRatePNG ) {
    dc.drawBitmap(50, 50, heartPNG );
    View.onUpdate(dc);
    }

    }
  • Former Member
    Former Member over 8 years ago
    I think i got it!!!

    Thanks to Travis's previous comment! Exactly what i was looking for:

    https://forums.garmin.com/showthread.php?283756-Tips-and-tricks-for-a-MonkeyC-Noob&p=645717#post645717
  • Glad you found a solution, but sorry I wasn't able to help out. I don't always have time during the work day to respond to posts.

    Travis