Skip to main content
Version: Next

Changing UI Properties on Runtime

There will always be a need to change properties of an UI element on runtime. Across the API reference and the guides on Smartface, you will encounter two types of assigning a property to an UI element.

If you want to assign custom properties using the code, you can use component.dispatch as follows:

function changeMargin(): void {
this.marginTop = 5; // Wrong. The property will be set but the UI will not be updated.
this.backgroundColor = Color.RED; // Wrong. The property will be set but the UI will not be updated.
this.dispatch({
type: "updateUserStyle",
userStyle: {
marginTop: 5,
backgroundColor: "#FF0000" // Note that Color.RED will not work here.
}
});
this.layout.applyLayout(); // Perform this when position related properties to be changed
}

About differences of properties

caution

When using direct assignment, you need to use their underlying property as a value. However, when using style you need to use string or number values since we are simulating to assign JSON variables.

For example, this will not work:

  // DO NOT USE THIS CODE
this.dispatch({
type: "updateUserStyle",
userStyle: {
positionType: FlexLayout.PositionType.ABSOLUTE,
backgroundColor: Color.RED
}
});

Those variables are often an enum and will be equivalent to this:

  // DO NOT USE THIS CODE
this.dispatch({
type: "updateUserStyle",
userStyle: {
positionType: 1 // Enum value of the PositionType.ABSOLUTE variable. It is used for different purposes in native.
backgroundColor: -65536 // Decimal representation of RED color in Android native.
}
});

Difference between direct assignment and class assignment

There are two ways to update UI elements on Runtime:

  • Direct assignment
  • Using dispatch

Let's look at this snippet. It will hide or show the given container on two different methods:

function hideWrapperLayout() {
this.flexLayout1.height = 0;
this.flexLayout1.visible = false;
this.flexLayout1.positionType = FlexLayout.PositionType.RELATIVE;
this.layout.applyLayout();
}

function showWrapperLayout() {
this.flexLayout1.height = 300;
this.flexLayout1.visible = true;
this.flexLayout1.positionType = FlexLayout.PositionType.ABSOLUTE;
this.layout.applyLayout();
}

Two methods aim towards the same goal, hiding or showing the given layout.

However, using direct assignment is considered as anti-pattern and discouraged unless you are assigning an attribute. Refer here for updated list of attributes.

danger

Smartface uses underlying Context renderer for their UI rendering and keeping class based structure. By directly assigning those, context will not be informed about the change, therefore might cause unexpected behaviours like incorrect positioning or not applying the changes.

function setLabel() {
this.label1.text = "Smartface"; // This is correct, text is an attribute
this.label1.width = 100; // This is anti pattern, width is not an attribute
// Use dispatch like this to update the context and width of the element
this.label1.dispatch({
type: "updateUserStyle",
userStyle: {
width: 100,
},
});
this.applyLayout(); // ApplyLayout might be necessary, refer to applyLayout doc below
}
ApplyLayout

For more technical information about dispatch and applylayout, refer the contx and styler repositories made by Smartface.