change bitmap reference in runtime in my layout

Hi, I am working on a watch face that uses a layout that includes a text field and a bitmap:

<layout id="WatchFace">
<label id="textfield" x="center" y="center" font="Graphics.FONT_NUMBER_MEDIUM" justification="Graphics.TEXT_JUSTIFY_RIGHT" color="Graphics.COLOR_WHITE" />
<bitmap id="img" x="10 + (dc.getWidth() / 2)" y="(dc.getHeight() / 6) - 5" filename="myImage.png" />
</layout>

I would like to be able to change the bitmap reference in runtime and have tried to call setBitmap() but not sure how to reference the new bitmap file. I have all my bitmap files in the same folder as the layout.xml file, and have tried the following in onUpdate():

var bmp = View.findDrawableById("img");
bmp.setBitmap("anotherImage.png");

but then I get the following exception:

Error: Unhandled Exception
Exception: UnexpectedTypeException: Expected Number/Float/Boolean/Long/Double, given String
Stack:
- setBitmap() at T:\mbsimulator\submodules\technology\monkeybrains\virtual-machine\api\WatchUi.mb:4222 0x30003acc
- onUpdate() at C:\Users\fredrik\eclipse-workspace\NSFace\source\NSFaceView.mc:52 0x100004b6

I did also try to define all the bitmaps in drawables.xml:

<drawables>
<bitmap id="myImage" filename="myImage.png" />
<bitmap id="anotherImage" filename="anotherImage.png" />
</drawables>

and tried this in onUpdate():

var bmp = View.findDrawableById("img");
bmp.setBitmap(Toybox.WatchUi.loadResource(Rez.Drawables.anotherImage));

I have obviously not understood how to use setBitmap(), or do I need to ditch layouts and use dc.draws instead? I kind of like the layout approach so was hoping I could use it. Im compiling this for one watch type only and the bitmaps will be updated once every 5 mins at most.  

Top Replies

All Replies

  • According to the documentation for Bitmap::setBitmap, the parameter is a Symbol (not a String, and not a BitmapResource). The following code can be used to verify this works.

    using Toybox.Application;
    using Toybox.WatchUi;
    
    class SimpleBehaviorDelegate extends WatchUi.BehaviorDelegate {
    
        hidden var _view;
    
        function initialize(view) {
            BehaviorDelegate.initialize();
            _view = view;
        }
    
        function onSelect() {
            _view.changeBitmap();
            return true;
        }
    }
    
    class SimpleView extends WatchUi.View {
    
        hidden var _bitmaps;
        hidden var _selection;
    
        function initialize() {
            View.initialize();
        }
    
        function onLayout(dc) {
            _selection = 0;
            _bitmaps = [
                Rez.Drawables.CheckOn,
                Rez.Drawables.CheckOff
            ];
    
            var layout = Rez.Layouts.Layout(dc);
            if (layout != null) {
                setLayout(layout);
            }
        }
    
        function changeBitmap() {
            var bitmap = findDrawableById("img");
            if (bitmap != null) {
                bitmap.setBitmap(_bitmaps[_selection]);
                _selection = (_selection + 1) % _bitmaps.size();
            }
            WatchUi.requestUpdate();
        }
    
    }
    
    class SimpleApp extends Application.AppBase {
    
        function initialize() {
            AppBase.initialize();
        }
    
        function getInitialView() {
            var view = new SimpleView();
            return [ view, new SimpleBehaviorDelegate(view) ];
        }
    
    }
    

  • Hi Travis, I forgot to thank you for this one. Your example worked perfect for me! Could never have done it without your help