NativeScript is an awesome framework for building cross-platform applications. It’s aimed at developers working with the holy trinity of web development, a.k.a HTML, Javascript and CSS.
While Javascript in NativeScript is the same Javascript we’re writing today (of course, using NativeScript modules and libraries), HTML and CSS aren’t. CSS in NativeScript is a subset of what we can use in browsers. And there is no HTML. Instead, we use XML for our views.
This means there aren’t divs, h1 through h6, ul, body, head and basically anything else we normally associate with HTML use to show content to the user.
Instead NativeScript exposes its own XML tags like Label
, Button
(as in Capital B) etc. The new tags are fairly intuitive and not likely to trip up a newbie. It’s how the elements are arranged on the page and behave relative to other elements that’s completely different from how things are done in HTML. And that’s what we’re going to explore in this post.
Grokking Layouts
In HTML, most things came with some default behaviour as to how they arrange themselves on a page. For example, if we don’t use any CSS, the following markup and its output are pretty easy to relate.
<html> <body> <label> This is HTML you know </label> <input type="text" placeholder="Enter something here"> <button> A button </button> </body> </html>
However, output of the NativeScript equivalent of the same markup looks bonkers.
<Page xmlns="http://schemas.nativescript.org/tns.xsd"> <Label text="This is NativeScript XML you don't know" /> <TextField hint="Enter something here" /> <Button text="A Button"/> </Page>
Where’s the label? Or the text field? Ignore the header bar. NativeScript adds it by default and sets the title to whatever we name our project.
Here’s the rub. Unlike HTML, which is meant for creating views, XML is a free data interchange format. This means that in a vanilla XML file, a Button
doesn’t mean something that should be displayed and tapped any more than Onion
.
NativeScript provides a variety of view components like button, inputs, selectors out of the box, but they don’t have any information encoded in them to determine how they are actually placed on a page. So each component ends up occupying the full height and width of its container. Since the above markup has Button
as the last component, we see only that.
Layouts are a way to tame this behaviour. They are, in the simplest of terms, rules that define how their children are positioned and sized on a page.
In HTML, we adjust how containers and elements are positioned by setting CSS properties like float
, flex
, width
, margin
etc.
In NativeScript, we simply choose one of the layouts as a parent container for our view components which applies a default characteristic behaviour to its children and then take it from there. In other words, properties like margin
etc. are used more for cosmetic purposes (like they should be IMO) rather than helping to facilitate positioning of an element relative to others.
For example, one of the most commonly used layouts is StackLayout
. It places each element below or beside its previous sibling, depending on whether we set its orientation as vertical or horizontal. Vertical orientation is the default. Let’s look at how it’s used and the effect it has on our XML markup above.
<Page xmlns="http://schemas.nativescript.org/tns.xsd"> <StackLayout> <Label text="This is NativeScript XML you don't know" /> <TextField hint="Enter something here" /> <Button text="A Button"/> </StackLayout> </Page>
That’s more like it. Simply adding a layout told our elements how to position themselves on the page.
StackLayout is a rather simplistic layout. That said, if we think of a login page, we probably visualize an email field of preferably full width with a password field below it, followed by a sign-in button. Many login pages (among other things) might be easily constructed with this layout.
Additionally, here’s a quick look at the GridLayout, which can be thought of as a table where we can specify number of rows and columns. Each of its children will occupy one of the cells. Elements can be set to occupy more than one row or column (again, like the tables in HTML).
<Page xmlns="http://schemas.nativescript.org/tns.xsd"> <GridLayout rows="*, *" columns="2*, *"> <Label text="This is NativeScript XML you don't know" row="0" colSpan="2" /> <TextField hint="Enter something here" row="1" col="0" /> <Button text="A Button" row="1" col="1"/> </GridLayout> </Page>
This layout specifies two rows and two columns. The rows are both set to fill all of the available space, which, in the case of two rows means each occupies half screen. The first column is set to be twice as wide as the second column. The Label
is placed on the first row and is set to occupy both columns. The TextField
occupies the first column of the second row while the Button
occupies the last remaining block in the second row and column.
GridLayout is evidently more flexible than StackLayout. But with power comes complexity. It should be a rule of thumb not to use a more complex layout if we don’t need it and can’t see it being needed in the foreseeable future.
Layouts can also be nested. So we could have included a StackLayout
in the top row of the grid and positioned some elements like list in it. With layout nesting and sizing, we can structure our page in any imaginable way. Here’s a quick example of this. Note that this can be as complex as we want to make it; although the performance penalty also starts racking up with complexity.
<Page xmlns="http://schemas.nativescript.org/tns.xsd"> <GridLayout rows="*, *" columns="2*, *"> <StackLayout row="0" colSpan="2" horizontalAlignment="center"> <Label text="Stack row 1"/> <Label text="Stack row 2"/> <Label text="Stack row 3"/> </StackLayout> <TextField hint="Enter something here" row="1" col="0" /> <Button text="A Button" row="1" col="1"/> </GridLayout> </Page>
We saw only a couple types of layouts available in NativeScript. There are also DockLayout, WrapLayout and AbsoluteLayout. The latter works pretty much the same way, which we can guess by its name. We define each element’s position in x and y pixels. All these layouts are good choices for different scenarios and add to the flexibility we have when structuring our views.
Conclusion
Hopefully this post has been able to clear up some of the confusion a programmer coming from HTML might have about how to use markups. Layouts are a powerful and flexible way of separating positioning from actual styling and isolating the behaviour of a set of elements from others on a page.
I’d be happy to take any comments (either below or on Twitter) for improvement of this post and any further discussions contrasting them with HTML based layout capabilities. Thanks for reading!
Akash Agrawal
Related Posts
-
Custom Components in NativeScript
ul { list-style: circle outside; } There aren't too many things as satisfying as doing…
-
Using ES2016 Decorators in React Native
*picture courtesy of pixabayDecorators are a popular bit of functionality currently in Stage 1 of…