一、variables.scss
大家在開始研究時,會發現在src/theme中有一個variables.scss檔案,variables.scss用于修改應用程式共享變量。可以編輯用于設定應用程式的預設顔色$ list-background-color,$ checkbox-ios-background-color-on等的$ colors映像的預設值。在此處設定會立即起作用,不友善主題化/換膚的完成。
另外,app.scss的優先級高于variables.scss,app.scss的作用域是全局性的,相同的變量标簽,app.scss裡面的資料會覆寫variables.scss裡面的資料。
二、自定義主題----換膚
官方雖然給出了主題化的文檔 點選打開連結,但是并不能滿足我們換膚的要求,是以, 原理:ionic2的換膚的原理和Web前端的換膚原理是一樣,利用scss設定成不同套的皮膚,通過全局變量,動态的變換主題/皮膚。ionic3同理。
環境:node ----7.7.3
npm ----4.6.1
ionic ----2.2.3
兩個主題/皮膚:test1和test2。
1、建立全局變量app.global.ts
在src/app中建立一個新檔案----app.global.ts,方式如下:

在空白處輸入“app.global.ts”。 然後,複制粘貼下面的内容。
import { Injectable } from '@angular/core';
@Injectable()
export class AppState {
_state = {}
constructor() {
}
get state() {
return this._state = this._clone(this._state);
}
set state(value) {
throw new Error('do not mutate the `.state` directly');
}
get(prop?: any) {
const state = this.state;
return state.hasOwnProperty(prop) ? state[prop] : state;
}
set(prop: string, value: any) {
return this._state[prop] = value;
}
_clone(object) {
return JSON.parse(JSON.stringify(object));
}
}
然後将檔案添加到app.module.ts中,
import { AppState } from './app.global';
2、修改app.html
定義一段代碼來改變主題。
<div class="{{global.state['theme']}}">
<ion-menu type="push" [content]="content">
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
<ion-nav [root]="rootPage" #content swipeBackEnabled="false">
</ion-nav>
</div>
3、修改app.component.ts
如下,
import { AppState } from './app.global';
import { HomePage } from '../pages/home/home';
import { AboutPage } from "../pages/about/about";
import { ContactPage } from "../pages/contact/contact";
@Component({
templateUrl: 'app.html'
})
export class MyApp {
@ViewChild(Nav) nav:Nav;
rootPage:any = TabsPage;
pages:Array<{title:string,component:any}>;
state:any;
constructor(platform: Platform,
statusBar: StatusBar,
splashScreen: SplashScreen,
public global:AppState) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
});
this.pages=[{title:'Home',component:HomePage},
{title:'tabs',component:TabsPage},
{title:'about',component:AboutPage},
{title:'contact',component:ContactPage}
];
}
openPage(page) {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
this.nav.setRoot(page.component);
}
}
4、設定主題/皮膚
在src/theme中建立scss檔案,建立方式同上1。
test1.theme.scss
.test1-theme{
transition: all 1s ease;
background-color: #f7acbc;
h2{
color: #ef5b9c;
font-size: 11px;
}
p{
color: #f58220;
font-size: 30px;
}
body,
div{
transition: all 1s ease;
color: #69541b;
}
.toolbar-background{
transition: all 1s ease;
background-color: #ed1941 !important ;
}
.home-Secondary{
background-color: #ffe600;
color: #705628;
}
ion-content{
transition: all 1s ease;
background-color: #50b7c1;
}
ion-item{
background-color: #ffe600;
}
.tabbar{
background-color: #705628;
.tab-button-text{
color: red;
}
}
.images{
background-image: url(https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1496920020490&di=271ab4eb354117d4ec2d588fe6520c0f&imgtype=0&src=http%3A%2F%2Fww2.sinaimg.cn%2Flarge%2F85cccab3gw1eteida5b0ag20dw0ay7vv.jpg);
background-repeat: no-repeat;
height: 300px;
width: 300px;
}
.DefaultBtn{
width: 100px;
height: 10px;
background-color: #78a355;
font-size: 11px;
}
}
test2.theme.scss
.test2-theme{
transition: all 1s ease;
background-color: #84bf96;
h2{
color: #694d9f;
font-size: 44px;
}
p{
color: #1d953f;
font-size: 9px;
}
body,
div{
transition: all 1s ease;
color: #009ad6;
}
.toolbar-background{
transition: all 1s ease;
background-color: #411445 !important;
}
.home-Secondary{
background-color: #9d9087;
color: #009ad6;
}
ion-content{
transition: all 1s ease;
background-color: #ffe600;
}
ion-item{
background-color: #84bf96;
}
.tabbar{
background-color: #f173ac;
.tab-button-text{
color: #ffe600;
}
}
.images{
background-image: url(http://pic15.nipic.com/20110703/6322714_103035354389_2.jpg);
background-repeat: no-repeat;
height: 600px;
width: 200px;
}
.DarkBtn{
height: 150px;
widows: 300px;
background-color: #ea66a6;
color: #1d953f ;
font-size: 22px;
}
}
注意:①、由于該皮膚是用于全局,是以,相同的标簽,即使不在同一檔案,如果需要不同的效果,也需要設定通配符;
②、如果需要改變圖檔,那麼,在設定初始圖檔時,圖檔的URL不要直接放在html檔案,放在與其配套的scss檔案中,這樣圖檔才能随換膚而改變。
然後,把皮膚檔案放在app.scss中,
@import '../theme/test1.theme';
@import '../theme/test2.theme';
5、設定換膚/主題按鈕事件
本人在about檔案裡面做了設定。
about.html
<ion-content padding>
<button class="DefaultBtn" ion-button (click)="changeTheme('test1-theme')">test1</button>
<button class="DarkBtn" ion-button color="dark" (click)="changeTheme('test2-theme')">test2</button>
</ion-content>
注意:點選事件的參數與皮膚檔案的入口參數是一一對應的。
about.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { AppState } from '../../app/app.global';
@Component({
selector: 'page-about',
templateUrl: 'about.html'
})
export class AboutPage {
constructor(public navCtrl: NavController,
public global: AppState
) {
}
changeTheme(theme) {
this.global.set('theme', theme);
}
}
總結:這種主題化/換膚方式滿足各種視圖變換背景色、frame,圖檔改變,字型顔色、大小、類型。
測試結果:
參考資料: http://www.discoversdk.com/blog/custom-themes-in-ionic-2-integrating-different-themes-in-application https://www.joshmorony.com/a-guide-to-styling-an-ionic-2-application/