NativeScript 样式主题 #
样式概述 #
NativeScript 使用 CSS 子集来为原生组件设置样式,让你可以用熟悉的 Web 技术美化应用。
text
┌─────────────────────────────────────────────────────────────┐
│ 样式系统 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 样式来源 │
│ ├── 内联样式 style="color: red;" │
│ ├── CSS 类 class="title" │
│ ├── 全局样式 app.css │
│ └── 主题样式 @nativescript/theme │
│ │
│ 样式特性 │
│ ├── CSS 选择器 │
│ ├── 平台特定样式 │
│ ├── 状态样式 │
│ └── 响应式设计 │
│ │
└─────────────────────────────────────────────────────────────┘
CSS 基础 #
内联样式 #
xml
<Label text="Hello" style="color: red; font-size: 20; background-color: #f0f0f0;" />
CSS 类 #
xml
<Label text="Hello" class="title primary" />
css
.title {
font-size: 24;
font-weight: bold;
}
.primary {
color: #3498db;
}
全局样式 #
在 app.css 中定义全局样式:
css
/* app.css */
/* 页面样式 */
Page {
background-color: #f5f5f5;
}
/* ActionBar 样式 */
ActionBar {
background-color: #3498db;
color: white;
}
/* 通用类 */
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
/* 间距 */
.p-10 { padding: 10; }
.p-20 { padding: 20; }
.m-10 { margin: 10; }
.m-20 { margin: 20; }
/* 字体大小 */
.h1 { font-size: 32; }
.h2 { font-size: 24; }
.h3 { font-size: 20; }
.h4 { font-size: 18; }
支持的 CSS 属性 #
文本样式 #
| 属性 | 说明 | 示例 |
|---|---|---|
| color | 文本颜色 | color: #333; |
| font-size | 字体大小 | font-size: 16; |
| font-weight | 字体粗细 | font-weight: bold; |
| font-family | 字体名称 | font-family: Arial; |
| font-style | 字体样式 | font-style: italic; |
| text-align | 文本对齐 | text-align: center; |
| text-decoration | 文本装饰 | text-decoration: underline; |
| text-transform | 文本转换 | text-transform: uppercase; |
| letter-spacing | 字母间距 | letter-spacing: 1; |
| line-height | 行高 | line-height: 1.5; |
盒模型 #
| 属性 | 说明 | 示例 |
|---|---|---|
| width | 宽度 | width: 100; |
| height | 高度 | height: 50; |
| margin | 外边距 | margin: 10; |
| padding | 内边距 | padding: 10; |
| border-width | 边框宽度 | border-width: 1; |
| border-color | 边框颜色 | border-color: #ccc; |
| border-radius | 圆角 | border-radius: 8; |
背景 #
| 属性 | 说明 | 示例 |
|---|---|---|
| background-color | 背景颜色 | background-color: #fff; |
| background-image | 背景图片 | background-image: url('~/bg.png'); |
| background-repeat | 背景重复 | background-repeat: no-repeat; |
| background-position | 背景位置 | background-position: center; |
| background-size | 背景大小 | background-size: cover; |
布局 #
| 属性 | 说明 | 示例 |
|---|---|---|
| horizontal-align | 水平对齐 | horizontal-align: center; |
| vertical-align | 垂直对齐 | vertical-align: center; |
| visibility | 可见性 | visibility: visible; |
| opacity | 透明度 | opacity: 0.5; |
| z-index | 层级 | z-index: 10; |
选择器 #
类型选择器 #
css
/* 选择所有 Label */
Label {
color: #333;
}
/* 选择所有 Button */
Button {
background-color: #3498db;
color: white;
}
类选择器 #
css
.title {
font-size: 24;
font-weight: bold;
}
.primary {
color: #3498db;
}
ID 选择器 #
css
#header {
background-color: #3498db;
}
xml
<StackLayout id="header">
<!-- ... -->
</StackLayout>
后代选择器 #
css
/* 选择 StackLayout 内的所有 Label */
StackLayout Label {
color: #333;
}
/* 选择 ListView 内的 Label */
ListView Label {
font-size: 14;
}
组合选择器 #
css
/* 同时选择多个类型 */
Label, Button {
color: #333;
}
/* 选择同时有多个类的元素 */
.title.primary {
font-size: 24;
color: #3498db;
}
平台特定样式 #
使用平台类 #
css
/* Android 特定样式 */
.android .title {
font-size: 20;
}
/* iOS 特定样式 */
.ios .title {
font-size: 24;
}
使用平台属性 #
xml
<Label text="Hello"
android:style="color: red;"
ios:style="color: blue;" />
使用 @supports #
css
@supports (font-size: 16) {
Label {
font-size: 16;
}
}
状态样式 #
交互状态 #
css
/* 按下状态 */
Button:active {
background-color: #2980b9;
}
/* 禁用状态 */
Button:disabled {
opacity: 0.5;
}
/* 聚焦状态 */
TextField:focus {
border-color: #3498db;
}
状态类 #
xml
<Button text="Click" class="btn" tap="onTap" />
typescript
export function onTap(args) {
const button = args.object as Button;
button.className = 'btn pressed';
}
css
.btn {
background-color: #3498db;
}
.btn.pressed {
background-color: #2980b9;
}
主题系统 #
安装主题 #
bash
npm install @nativescript/theme
引入主题 #
css
/* app.css */
@import '@nativescript/theme/css/core.css';
@import '@nativescript/theme/css/default.css';
主题变量 #
css
/* 自定义主题变量 */
@import '@nativescript/theme/css/core.css';
:root {
--primary: #3498db;
--secondary: #95a5a6;
--success: #2ecc71;
--danger: #e74c3c;
--warning: #f39c12;
--info: #17a2b8;
--background: #ffffff;
--text-color: #333333;
--font-size-base: 16;
--border-radius: 8;
}
使用主题类 #
xml
<!-- 按钮 -->
<Button text="Primary" class="btn btn-primary" />
<Button text="Secondary" class="btn btn-secondary" />
<Button text="Outline" class="btn btn-outline" />
<!-- 文本 -->
<Label text="Title" class="text-primary h2" />
<Label text="Subtitle" class="text-secondary" />
<!-- 卡片 -->
<StackLayout class="card">
<Label text="Card Title" class="card-title" />
<Label text="Card content" class="card-text" />
</StackLayout>
暗黑模式 #
检测暗黑模式 #
typescript
import { Application, Frame } from '@nativescript/core';
// 获取当前模式
const isDarkMode = Application.systemAppearance() === 'dark';
// 监听模式变化
Application.on(Application.systemAppearanceChangedEvent, (args) => {
console.log('System appearance:', args.newValue);
updateTheme(args.newValue);
});
实现暗黑模式 #
css
/* app.css */
/* 浅色模式(默认) */
Page {
background-color: #ffffff;
}
Label {
color: #333333;
}
/* 暗黑模式 */
Page.dark {
background-color: #1a1a1a;
}
Page.dark Label {
color: #ffffff;
}
Page.dark ActionBar {
background-color: #2d2d2d;
color: #ffffff;
}
typescript
// 应用主题
function updateTheme(appearance: string) {
const page = Frame.topmost().currentPage;
if (appearance === 'dark') {
page.className = 'dark';
} else {
page.className = '';
}
}
SCSS 支持 #
配置 SCSS #
bash
npm install sass --save-dev
使用 SCSS #
scss
// _variables.scss
$primary: #3498db;
$secondary: #95a5a6;
$success: #2ecc71;
$danger: #e74c3c;
$font-size-base: 16;
$border-radius: 8;
// _mixins.scss
@mixin button-variant($background, $color) {
background-color: $background;
color: $color;
border-radius: $border-radius;
padding: 12 24;
&:active {
background-color: darken($background, 10%);
}
}
// app.scss
@import 'variables';
@import 'mixins';
Page {
background-color: #f5f5f5;
}
.btn-primary {
@include button-variant($primary, white);
}
.btn-danger {
@include button-variant($danger, white);
}
响应式设计 #
屏幕尺寸 #
typescript
import { Screen } from '@nativescript/core';
const screenWidth = Screen.mainScreen.widthDIPs;
const screenHeight = Screen.mainScreen.heightDIPs;
const scale = Screen.mainScreen.scale;
响应式类 #
typescript
// 响应式工具类
export class Responsive {
static isPhone(): boolean {
return Screen.mainScreen.widthDIPs < 600;
}
static isTablet(): boolean {
return Screen.mainScreen.widthDIPs >= 600;
}
static isLandscape(): boolean {
return Screen.mainScreen.widthDIPs > Screen.mainScreen.heightDIPs;
}
}
响应式样式 #
xml
<GridLayout columns="{{ isTablet ? '200, *' : '*' }}">
<StackLayout col="0" visibility="{{ isTablet ? 'visible' : 'collapsed' }}">
<!-- 侧边栏(仅平板显示) -->
</StackLayout>
<GridLayout col="{{ isTablet ? 1 : 0 }}">
<!-- 主内容 -->
</GridLayout>
</GridLayout>
样式最佳实践 #
组织样式文件 #
text
app/
├── app.css # 全局样式
├── scss/
│ ├── _variables.scss # 变量
│ ├── _mixins.scss # 混合宏
│ ├── _buttons.scss # 按钮样式
│ ├── _forms.scss # 表单样式
│ ├── _typography.scss # 排版
│ └── app.scss # 主样式文件
└── pages/
├── home/
│ └── home.css # 页面特定样式
└── detail/
└── detail.css
命名规范 #
css
/* 使用 BEM 命名 */
.card {}
.card__title {}
.card__content {}
.card--featured {}
/* 使用语义化类名 */
.header {}
.footer {}
.sidebar {}
.main-content {}
/* 使用状态类 */
.is-active {}
.is-disabled {}
.is-loading {}
性能优化 #
css
/* 避免深层嵌套 */
/* 不推荐 */
StackLayout GridLayout StackLayout Label {
color: #333;
}
/* 推荐 */
.nested-label {
color: #333;
}
/* 避免通配符 */
/* 不推荐 */
* {
margin: 0;
}
/* 推荐 */
Page, StackLayout, GridLayout {
margin: 0;
}
常用样式模式 #
按钮样式 #
css
.btn {
padding: 12 24;
border-radius: 8;
font-size: 16;
font-weight: 500;
min-width: 100;
}
.btn-primary {
background-color: #3498db;
color: white;
}
.btn-secondary {
background-color: #95a5a6;
color: white;
}
.btn-success {
background-color: #2ecc71;
color: white;
}
.btn-danger {
background-color: #e74c3c;
color: white;
}
.btn-outline {
background-color: transparent;
border-width: 2;
border-color: #3498db;
color: #3498db;
}
.btn-block {
width: 100%;
}
.btn-sm {
padding: 8 16;
font-size: 14;
}
.btn-lg {
padding: 16 32;
font-size: 18;
}
卡片样式 #
css
.card {
background-color: white;
border-radius: 12;
margin: 10;
padding: 15;
/* 阴影效果 */
box-shadow: 0 2 4 rgba(0,0,0,0.1);
}
.card-header {
font-size: 18;
font-weight: bold;
margin-bottom: 10;
}
.card-body {
font-size: 14;
color: #666;
}
.card-footer {
margin-top: 15;
horizontal-align: right;
}
表单样式 #
css
.form-group {
margin-bottom: 15;
}
.form-label {
font-size: 14;
color: #666;
margin-bottom: 5;
}
.form-control {
border-width: 1;
border-color: #ddd;
border-radius: 8;
padding: 12;
font-size: 16;
}
.form-control:focus {
border-color: #3498db;
}
.form-error {
color: #e74c3c;
font-size: 12;
margin-top: 5;
}
下一步 #
现在你已经掌握了样式主题,接下来学习 插件系统,扩展应用的功能!
最后更新:2026-03-29