Layout.xml with two layout ids

Help!
For the same specific watch (lets assume 920) - I would like to describe two different layouts that would be initiated after a "App.getApp().getProperty" code.

As i'm doing the initial watch layout @ Layout.xml, i was wondering to setup those two layouts (that uses different images) - but they just ovelap and load all of them in sequence!

<resources>
<layout id="WatchFace">
<bitmap id="logo" x="center" y="20" filename="../IMAGE1" />
</layout id>

<layout id="WatchFaceB">
<bitmap id="logo" x="center" y"20" filename="../IMAGE2" />
</layout id>
</resources>




function onLayout(dc)
{
if ( Property == 0 )
{
setLayout(Rez.Layouts.WatchFace(dc));
}
else
{
setLayout(Rez.Layouts.WatchFaceB(dc));
}
}


Any ideias why this approach is not working?
Best regards,
  • I'd first check if position is always the same when you enter this code "Sys.println(Property.toString()";

    I'd suspect that your not doing the getProperty() until after onLayout() is called.

    Try putting the "getProperty()" in your "initialize()" function.
  • I'd first check if position is always the same when you enter this code "Sys.println(Property.toString()";

    I'd suspect that your not doing the getProperty() until after onLayout() is called.

    Try putting the "getProperty()" in your "initialize()" function.


    Sorry Jim
    But could you be more specific? println is returning properly the variable, but as i mentioned, appears that the issue is on the layout.xml part of the game (maybe i'm wrong!)
    Thanks in advance
    EB
  • <resources>
    <layout id="WatchFace">
    <bitmap id="logo" x="center" y="20" filename="../IMAGE1" />
    </layout id>

    <layout id="WatchFaceB">
    <bitmap id="logo" x="center" y"20" filename="../IMAGE2" />
    </layout id>
    </resources>


    The problem is your incorrect closing </layout id> elements.
    They should be </layout>
  • Just to add, I've trying with the Samples codeing, without success... It layouts both (and not a single as requested)

    <layouts>
    <!-- WHITE BACKGROUND. -->
    <layout id="WatchFaceWhite">
    <drawable class="Background" />
    <bitmap id="logo" x="center" y="20" filename="../drawables/imageA.png" />
    </layout>

    <!-- BLACK BACKGROUND-->
    <layout id="WatchFace">
    <drawable class="Background" />
    <bitmap id="logo" x="center" y="20" filename="../drawables/imageB.png" />
    </layout>
    </layouts>



    if ( BackgroundSetting == 0 )
    {
    Sys.println(BackgroundSetting.toString());
    View.setLayout(Rez.Layouts.WatchFace(dc));

    }

    else if (BackgroundSetting == 1)
    {
    Sys.println(BackgroundSetting.toString());
    View.setLayout(Rez.Layouts.WatchFaceWhite(dc));
    }


    The above "if" is working as desired....
  • I managed to get it working as follows:

    In YourApp.mc in onSettingsChanged(), you could re-instantiate your view and switch to it as follows:

    function onSettingsChanged() {
    Ui.switchToView(new YourView(), null, Ui.SLIDE_IMMEDIATE);
    }


    Hope this works for you too. I can now change my layout based on user settings in the watchface.
  • I managed to get it working as follows:

    In YourApp.mc in onSettingsChanged(), you could re-instantiate your view and switch to it as follows:

    function onSettingsChanged() {
    Ui.switchToView(new YourView(), null, Ui.SLIDE_IMMEDIATE);
    }


    Hope this works for you too. I can now change my layout based on user settings in the watchface.



    Actually, it is not changing, as i try to push the new layouts, it just read all layouts. - This instance already has the "Ui.requestUpdate();" which requests to update when settings changed.
    I found on the SDK documentation:

    - (Object) setLayout(layout)

    Use setLayout() to set the layout for the View. If the extending class does not override onUpdate(), then all Drawables contained in layout will automatically be drawn by the View.

    Parameters:
    layout (Array) — An array of Drawables


    Glad to see that "all drawables contained in layout will automatically be drawn" statement. Would be the issue??
  • Actually, it is not changing, as i try to push the new layouts, it just read all layouts. - This instance already has the "Ui.requestUpdate();" which requests to update when settings changed.
    I found on the SDK documentation:

    - (Object) setLayout(layout)

    Use setLayout() to set the layout for the View. If the extending class does not override onUpdate(), then all Drawables contained in layout will automatically be drawn by the View.

    Parameters:
    layout (Array) — An array of Drawables


    Glad to see that "all drawables contained in layout will automatically be drawn" statement. Would be the issue??


    I believe that once inside the view, you cannot use the setLayout after the onLayout has been called.
    That is why I have moved the logic into my AppBase class which controls "restarting" the watchface by instantiating a new view and switching to it. This way it forces the onLayout to be called.

    I think setLayout is sensitive to the lifecycle of a view and only works when called in onLayout.
    Because of this belief I was looking at the "restart" mechanism as explained above.
    There seem to be no impact on memory as far as I can see.
  • I believe that once inside the view, you cannot use the setLayout after the onLayout has been called.
    That is why I have moved the logic into my AppBase class which controls "restarting" the watchface by instantiating a new view and switching to it. This way it forces the onLayout to be called.

    I think setLayout is sensitive to the lifecycle of a view and only works when called in onLayout.
    Because of this belief I was looking at the "restart" mechanism as explained above.
    There seem to be no impact on memory as far as I can see.


    No good! :((((((

    Four long days searching trying to solve this!
  • Former Member
    Former Member over 9 years ago
    I don't know why you have trouble switching the layout. I've tried it without any problem:

    My layout:
    <layouts>
    <layout id="WatchFace">
    <label id="TimeLabel" x="center" y="center" font="Gfx.FONT_LARGE" justification="Gfx.TEXT_JUSTIFY_CENTER" color="Gfx.COLOR_BLUE" />
    </layout>
    <layout id="WatchFaceAlt">
    <label id="TimeLabel" x="center" y="center" font="Gfx.FONT_LARGE" justification="Gfx.TEXT_JUSTIFY_CENTER" color="Gfx.COLOR_RED" />
    </layout>
    </layouts>


    using Toybox.WatchUi as Ui;
    using Toybox.Graphics as Gfx;
    using Toybox.System as Sys;
    using Toybox.Lang as Lang;

    class testSwitchLayoutView extends Ui.WatchFace
    {
    var first = true;
    var switchLayout = false;

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

    //! Load your resources here
    function onLayout(dc) {
    if (first) {
    setLayout(Rez.Layouts.WatchFace(dc));
    }
    else {
    setLayout(Rez.Layouts.WatchFaceAlt(dc));
    }

    first = !first;
    switchLayout = false;
    }

    //! Update the view
    function onUpdate(dc) {
    if (switchLayout) {
    onLayout(dc);
    }

    // Get and show the current time
    var clockTime = Sys.getClockTime();
    var timeString = Lang.format("$1$:$2$", [clockTime.hour, clockTime.min.format("%02d")]);
    var view = View.findDrawableById("TimeLabel");
    view.setText(timeString);

    // Call the parent onUpdate function to redraw the layout
    View.onUpdate(dc);
    }

    //! The user has just looked at their watch. Timers and animations may be started here.
    function onExitSleep() {
    switchLayout = true;
    }

    //! Terminate any active timers and prepare for slow updates.
    function onEnterSleep() {
    switchLayout = true;
    }
    }
  • I also had trouble, but found that complexities in my code caused my troubles.

    TeunMo's sample is simple. Try that and build it up until you run into issues, and then you will know better what you are doing wrong.

    I've discovered in my scenario that I have to make sure that I switch the layout first before setting anything on Views like colors. If I set colors on views and then switch layout, it does not behave as expected because the view that you set the color on, is not the same view because of the new layout that was set. The references are different.