NativeScript 布局系统 #
布局概述 #
NativeScript 提供了多种布局容器,用于组织界面元素的排列方式。
text
┌─────────────────────────────────────────────────────────────┐
│ 布局容器 │
├─────────────────────────────────────────────────────────────┤
│ │
│ StackLayout 堆叠布局(垂直/水平) │
│ GridLayout 网格布局 │
│ FlexboxLayout 弹性布局 │
│ AbsoluteLayout 绝对定位 │
│ DockLayout 停靠布局 │
│ WrapLayout 自动换行 │
│ │
└─────────────────────────────────────────────────────────────┘
StackLayout #
最简单的布局容器,子元素按顺序堆叠。
垂直堆叠(默认) #
xml
<StackLayout orientation="vertical">
<Label text="Item 1" height="50" backgroundColor="#3498db" />
<Label text="Item 2" height="50" backgroundColor="#2ecc71" />
<Label text="Item 3" height="50" backgroundColor="#e74c3c" />
</StackLayout>
text
┌─────────────────────────────────────┐
│ Item 1 │
├─────────────────────────────────────┤
│ Item 2 │
├─────────────────────────────────────┤
│ Item 3 │
└─────────────────────────────────────┘
水平堆叠 #
xml
<StackLayout orientation="horizontal">
<Label text="A" width="50" backgroundColor="#3498db" />
<Label text="B" width="50" backgroundColor="#2ecc71" />
<Label text="C" width="50" backgroundColor="#e74c3c" />
</StackLayout>
text
┌────────┬────────┬────────┐
│ A │ B │ C │
└────────┴────────┴────────┘
常用属性 #
| 属性 | 类型 | 说明 |
|---|---|---|
| orientation | string | 方向: vertical/horizontal |
子元素间距 #
xml
<StackLayout class="p-10">
<Label text="Item 1" class="m-b-10" />
<Label text="Item 2" class="m-b-10" />
<Label text="Item 3" />
</StackLayout>
GridLayout #
强大的网格布局,可以定义行和列。
基本用法 #
xml
<GridLayout rows="auto, *, auto" columns="*, *">
<Label text="Header" row="0" col="0" colSpan="2" backgroundColor="#3498db" />
<Label text="Left" row="1" col="0" backgroundColor="#2ecc71" />
<Label text="Right" row="1" col="1" backgroundColor="#e74c3c" />
<Label text="Footer" row="2" col="0" colSpan="2" backgroundColor="#9b59b6" />
</GridLayout>
text
┌─────────────────────────────────────┐
│ Header │
├──────────────────┬──────────────────┤
│ Left │ Right │
├──────────────────┴──────────────────┤
│ Footer │
└─────────────────────────────────────┘
行列定义 #
xml
<GridLayout rows="50, *, 2*, 100" columns="100, *, auto">
<!-- 行定义说明 -->
<!-- 50: 固定高度 50 -->
<!-- *: 占用剩余空间的一份 -->
<!-- 2*: 占用剩余空间的两份 -->
<!-- 100: 固定高度 100 -->
<!-- 列定义说明 -->
<!-- 100: 固定宽度 100 -->
<!-- *: 占用剩余空间 -->
<!-- auto: 根据内容自动 -->
</GridLayout>
常用属性 #
| 属性 | 类型 | 说明 |
|---|---|---|
| rows | string | 行定义 |
| columns | string | 列定义 |
| row | number | 子元素所在行 |
| col | number | 子元素所在列 |
| rowSpan | number | 跨行数 |
| colSpan | number | 跨列数 |
实际应用 #
xml
<!-- 登录表单 -->
<GridLayout rows="auto, auto, auto, auto" columns="*, *">
<Label text="Username:" row="0" col="0" colSpan="2" />
<TextField hint="Enter username" row="1" col="0" colSpan="2" />
<Label text="Password:" row="2" col="0" colSpan="2" />
<TextField hint="Enter password" secure="true" row="3" col="0" colSpan="2" />
<Button text="Login" row="4" col="0" />
<Button text="Register" row="4" col="1" />
</GridLayout>
FlexboxLayout #
类似 CSS Flexbox 的布局容器。
基本用法 #
xml
<FlexboxLayout flexDirection="row"
flexWrap="wrap"
justifyContent="space-between"
alignItems="center">
<Label text="1" width="30%" height="50" backgroundColor="#3498db" />
<Label text="2" width="30%" height="50" backgroundColor="#2ecc71" />
<Label text="3" width="30%" height="50" backgroundColor="#e74c3c" />
<Label text="4" width="30%" height="50" backgroundColor="#9b59b6" />
</FlexboxLayout>
flexDirection #
xml
<!-- 水平方向 -->
<FlexboxLayout flexDirection="row">
<Label text="A" />
<Label text="B" />
</FlexboxLayout>
<!-- 水平反向 -->
<FlexboxLayout flexDirection="row-reverse">
<Label text="A" />
<Label text="B" />
</FlexboxLayout>
<!-- 垂直方向 -->
<FlexboxLayout flexDirection="column">
<Label text="A" />
<Label text="B" />
</FlexboxLayout>
<!-- 垂直反向 -->
<FlexboxLayout flexDirection="column-reverse">
<Label text="A" />
<Label text="B" />
</FlexboxLayout>
justifyContent #
xml
<!-- 起点对齐 -->
<FlexboxLayout flexDirection="row" justifyContent="flex-start">
<!-- 终点对齐 -->
<FlexboxLayout flexDirection="row" justifyContent="flex-end">
<!-- 居中对齐 -->
<FlexboxLayout flexDirection="row" justifyContent="center">
<!-- 两端对齐 -->
<FlexboxLayout flexDirection="row" justifyContent="space-between">
<!-- 等间距 -->
<FlexboxLayout flexDirection="row" justifyContent="space-around">
alignItems #
xml
<!-- 交叉轴起点对齐 -->
<FlexboxLayout alignItems="flex-start">
<!-- 交叉轴终点对齐 -->
<FlexboxLayout alignItems="flex-end">
<!-- 交叉轴居中对齐 -->
<FlexboxLayout alignItems="center">
<!-- 拉伸填充 -->
<FlexboxLayout alignItems="stretch">
子元素属性 #
xml
<FlexboxLayout flexDirection="row">
<Label text="A" flexGrow="1" />
<Label text="B" flexShrink="1" />
<Label text="C" alignSelf="center" />
<Label text="D" order="-1" />
</FlexboxLayout>
| 属性 | 说明 |
|---|---|
| flexGrow | 放大比例 |
| flexShrink | 缩小比例 |
| flexWrapBefore | 是否换行 |
| alignSelf | 自身对齐方式 |
| order | 排列顺序 |
AbsoluteLayout #
绝对定位布局,子元素使用 top/left/right/bottom 定位。
xml
<AbsoluteLayout>
<Label text="Top Left" top="0" left="0"
width="100" height="50" backgroundColor="#3498db" />
<Label text="Top Right" top="0" right="0"
width="100" height="50" backgroundColor="#2ecc71" />
<Label text="Bottom Left" bottom="0" left="0"
width="100" height="50" backgroundColor="#e74c3c" />
<Label text="Bottom Right" bottom="0" right="0"
width="100" height="50" backgroundColor="#9b59b6" />
<Label text="Center" top="50%" left="50%"
width="100" height="50" backgroundColor="#f39c12" />
</AbsoluteLayout>
text
┌─────────────────────────────────────┐
│ Top Left Top Right │
│ │
│ Center │
│ │
│ Bottom Left Bottom Right │
└─────────────────────────────────────┘
应用场景 #
xml
<!-- 图片上的标签 -->
<AbsoluteLayout>
<Image src="~/assets/photo.jpg"
width="100%" height="200" stretch="aspectFill" />
<Label text="Featured"
top="10" left="10"
class="badge" />
</AbsoluteLayout>
DockLayout #
停靠布局,子元素可以停靠在四个边缘。
xml
<DockLayout stretchLastChild="true">
<Label text="Top" dock="top" height="50" backgroundColor="#3498db" />
<Label text="Bottom" dock="bottom" height="50" backgroundColor="#2ecc71" />
<Label text="Left" dock="left" width="100" backgroundColor="#e74c3c" />
<Label text="Right" dock="right" width="100" backgroundColor="#9b59b6" />
<Label text="Center" backgroundColor="#f39c12" />
</DockLayout>
text
┌─────────────────────────────────────┐
│ Top │
├─────────────────────────────────────┤
│ │ │ │
│ Left │ Center │ Right │
│ │ │ │
├─────────────────────────────────────┤
│ Bottom │
└─────────────────────────────────────┘
应用场景 #
xml
<!-- 应用框架 -->
<DockLayout>
<ActionBar dock="top" title="My App" />
<StackLayout dock="bottom" class="footer">
<Label text="Footer" />
</StackLayout>
<GridLayout>
<!-- 主内容 -->
</GridLayout>
</DockLayout>
WrapLayout #
自动换行布局。
xml
<WrapLayout orientation="horizontal" itemWidth="100" itemHeight="100">
<Label text="1" backgroundColor="#3498db" />
<Label text="2" backgroundColor="#2ecc71" />
<Label text="3" backgroundColor="#e74c3c" />
<Label text="4" backgroundColor="#9b59b6" />
<Label text="5" backgroundColor="#f39c12" />
<Label text="6" backgroundColor="#1abc9c" />
</WrapLayout>
text
┌────────┬────────┬────────┐
│ 1 │ 2 │ 3 │
├────────┼────────┼────────┤
│ 4 │ 5 │ 6 │
└────────┴────────┴────────┘
应用场景 #
xml
<!-- 标签云 -->
<WrapLayout class="tag-cloud">
<Label *ngFor="let tag of tags"
[text]="tag"
class="tag" />
</WrapLayout>
布局嵌套 #
复杂布局示例 #
xml
<GridLayout rows="auto, *, auto">
<!-- Header -->
<StackLayout row="0" class="header">
<Label text="My App" class="title" />
</StackLayout>
<!-- Content -->
<ScrollView row="1">
<FlexboxLayout flexDirection="column">
<!-- 用户信息 -->
<GridLayout columns="auto, *" class="user-info">
<Image col="0" src="{{ avatar }}" />
<StackLayout col="1">
<Label text="{{ name }}" />
<Label text="{{ email }}" />
</StackLayout>
</GridLayout>
<!-- 内容列表 -->
<StackLayout>
<Label *ngFor="let item of items" [text]="item.title" />
</StackLayout>
</FlexboxLayout>
</ScrollView>
<!-- Footer -->
<StackLayout row="2" class="footer">
<Button text="Action" tap="onAction" />
</StackLayout>
</GridLayout>
响应式布局 #
使用百分比 #
xml
<GridLayout columns="30%, 70%">
<Label text="Sidebar" col="0" />
<Label text="Content" col="1" />
</GridLayout>
使用星号比例 #
xml
<GridLayout columns="1*, 2*">
<Label text="1/3" col="0" />
<Label text="2/3" col="1" />
</GridLayout>
平台适配 #
xml
<GridLayout columns="{{ isTablet ? '200, *' : '*' }}">
<StackLayout col="0" visibility="{{ isTablet ? 'visible' : 'collapsed' }}">
<!-- 侧边栏(仅平板显示) -->
</StackLayout>
<GridLayout col="{{ isTablet ? 1 : 0 }}">
<!-- 主内容 -->
</GridLayout>
</GridLayout>
屏幕尺寸检测 #
typescript
import { Screen } from '@nativescript/core';
const screenWidth = Screen.mainScreen.widthDIPs;
const screenHeight = Screen.mainScreen.heightDIPs;
const isTablet = screenWidth >= 600;
布局性能 #
避免过度嵌套 #
xml
<!-- 不推荐 -->
<StackLayout>
<StackLayout>
<StackLayout>
<Label text="Content" />
</StackLayout>
</StackLayout>
</StackLayout>
<!-- 推荐 -->
<GridLayout>
<Label text="Content" />
</GridLayout>
使用 GridLayout 替代嵌套 #
xml
<!-- 不推荐 -->
<StackLayout orientation="horizontal">
<StackLayout>
<Label text="Title" />
<Label text="Subtitle" />
</StackLayout>
<Button text="Action" />
</StackLayout>
<!-- 推荐 -->
<GridLayout columns="*, auto" rows="auto, auto">
<Label text="Title" row="0" col="0" />
<Label text="Subtitle" row="1" col="0" />
<Button text="Action" row="0" col="1" rowSpan="2" />
</GridLayout>
常见布局模式 #
卡片布局 #
xml
<GridLayout rows="auto, auto, auto" class="card">
<Image src="{{ image }}" row="0" height="150" stretch="aspectFill" />
<StackLayout row="1" class="card-content">
<Label text="{{ title }}" class="title" />
<Label text="{{ description }}" textWrap="true" />
</StackLayout>
<StackLayout row="2" class="card-actions" orientation="horizontal">
<Button text="Like" />
<Button text="Share" />
</StackLayout>
</GridLayout>
表单布局 #
xml
<StackLayout class="form">
<GridLayout columns="100, *" rows="auto">
<Label text="Name:" col="0" verticalAlignment="center" />
<TextField col="1" hint="Enter name" />
</GridLayout>
<GridLayout columns="100, *" rows="auto">
<Label text="Email:" col="0" verticalAlignment="center" />
<TextField col="1" hint="Enter email" keyboardType="email" />
</GridLayout>
<Button text="Submit" class="btn-primary" />
</StackLayout>
列表项布局 #
xml
<GridLayout columns="auto, *, auto" rows="auto, auto" class="list-item">
<Image src="{{ avatar }}"
col="0" row="0" rowSpan="2"
width="50" height="50" borderRadius="25" />
<Label text="{{ name }}" col="1" row="0" class="name" />
<Label text="{{ message }}" col="1" row="1" class="message" />
<Label text="{{ time }}" col="2" row="0" class="time" />
</GridLayout>
下一步 #
现在你已经掌握了布局系统,接下来学习 导航路由,了解页面导航的实现方式!
最后更新:2026-03-29