Ionic—動態樣式與夜間模式
阿新 • • 發佈:2018-12-28
一.夜間模式的佈局實現
1.開發設計
-
夜間模式的切換其實就是css樣式表的切換
-
新增主題檔案theme[
theme.light.scss
和theme.dark.scss
] -
建立providers實現主題的切換
ionic g provider settings
-
rxjs中的BehaviorSubject用於行為管理,可以用來切換主題,使用方式如下
-
建立樣式主題
this.theme = new BehaviorSubject('light-theme');
-
設定主題方法
setActiveTheme(val){ this.theme.next(val); }
-
獲得當前主題
getActiveTheme() { return this.theme.asObservable(); }
-
2.例項程式碼
-
theme.light.scss
.light-theme { ion-content { background-color: #e3e4e7 } .toolbar-background { background-color: #fff; } .marginBottom0 { margin-bottom: 0!important; } }
-
theme.dark.scss
.dark-theme { ion-content,.card,.floatMenu { background-color: #1e2446 !important; color: #fff !important; } .toolbar-title { color: #fff !important; } .header .toolbar-background { border-color: #140414 !important; background-color: #3a3c4b !important; } .list,.label,.item{ background-color: #3a3c4b !important; color:#FFFFFF !important; } .item{ border-bottom: 0.55px solid #2e2749 !important; } .item-inner,{ border: none !important; } .item-block{ border-bottom: 0.55px solid #2e2749 !important; } }
-
variables.scss新增內容
//匯入你自定義的樣式 //這裡匯入的是兩套主題樣式 @import "theme.light"; @import "theme.dark";
-
more.html
<ion-header> <ion-navbar> <ion-title>更多</ion-title> </ion-navbar> </ion-header> <ion-content> <div *ngIf="!isLogined"> <ion-card> <ion-card-header text-center> Log in 'Free Skin' and experience more features... </ion-card-header> <ion-card-content text-center> <button ion-button outline (click)="presentLoginModal()"> Sign in / Sign up </button> </ion-card-content> </ion-card> </div> <div *ngIf="isLogined"> <ion-list class="marginTop0px"> <button ion-item (click)="editUserInfo()"> <ion-avatar item-start> <img [src]="avatarUrl"> </ion-avatar> <h2> {{userName}} </h2> <p>Click to edit your user info</p> </button> </ion-list> <ion-list class="marginTop10px"> <ion-list-header> 我的資訊 </ion-list-header> <button ion-item (click)="gotoDataList('question')"> <!-- 使用color屬性也可以給icon新增顏色,color中的值在theme中定義,可以直接給定顏色 --> <ion-icon name="paper" item-start color="primary"></ion-icon> <ion-label>我的直播</ion-label> </button> <button ion-item (click)="gotoDataList('favourite')"> <ion-icon name="star" item-start color="orange"></ion-icon> <ion-label>我的關注</ion-label> </button> <button ion-item (click)="gotoDataList('answer')"> <ion-icon name="disc" item-start color="secondary"></ion-icon> <ion-label>我的護膚</ion-label> </button> </ion-list> <ion-list class="marginTop10px"> <ion-list-header> 個人設定 </ion-list-header> <ion-item> <ion-icon name="cloudy-night" item-start color="purple"></ion-icon> <ion-label>夜間模式</ion-label> <!-- 左右切換小按鈕 --> <ion-toggle color="purple"></ion-toggle> </ion-item> </ion-list> </div> </ion-content>
-
settings.ts
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs/Rx'; @Injectable() export class SettingsProvider { //BehaviorSubject用於行為管理 private theme: BehaviorSubject<string>; constructor(public http: HttpClient) { this.theme = new BehaviorSubject('light-theme'); } //設定當前主題 setActiveTheme(val){ this.theme.next(val); } //獲得當前主題 getActiveTheme() { return this.theme.asObservable(); } }
二.夜間模式的功能實現
1.開發設計
- 在app.component上監聽(subscribe)settingsProvider,並獲取當前theme主題並賦值給元件屬性中,從而繫結html中全域性樣式是theme.light還是theme.dark
- 給more頁面的ion-toggle繫結ionChange事件從而實現切換樣式時觸發provider的主題切換,因為app.component監聽主題切換了,故實現點選切換選項時實現主題的變換
2.例項程式碼
-
app.component.ts
import { Component } from '@angular/core'; import { Platform } from 'ionic-angular'; import { StatusBar } from '@ionic-native/status-bar'; import { SplashScreen } from '@ionic-native/splash-screen'; import { TabsPage } from '../pages/tabs/tabs'; import { SettingsProvider } from '../providers/settings/settings'; @Component({ templateUrl: 'app.html' }) export class MyApp { rootPage:any = TabsPage; //當前的主題 selectedTheme:string=''; constructor( platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, settings: SettingsProvider) { //監聽主題的變換並切換當前值 settings.getActiveTheme().subscribe(val=>{ this.selectedTheme = val; }); 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(); }); } }
-
app.html
<ion-nav [root]="rootPage" [class]="selectedTheme"></ion-nav>
-
more.ts
import { Component } from '@angular/core'; import { NavController, NavParams, ModalController, LoadingController, ToastController } from 'ionic-angular'; import { LoginPage } from '../login/login'; import { Storage } from '@ionic/storage'; import { BaseUI } from '../../common/baseUI'; import { UserPage } from '../user/user'; import {UserdatalistPage} from '../userdatalist/userdatalist'; import { SettingsProvider } from '../../providers/settings/settings'; @Component({ selector: 'page-more', templateUrl: 'more.html', }) export class MorePage extends BaseUI{ //判斷是否登入 isLogined:boolean = false; //avatar url avatarUrl:string = "../../assets/imgs/logo.png"; //user name userName:string = "Jack_Wangzhe"; //當前主題 selectedTheme:string; constructor( public navCtrl: NavController, public navParams: NavParams, public modalCtrl: ModalController, public loadingCtrl:LoadingController, public toastCtrl:ToastController, public storage: Storage, public settings: SettingsProvider) { super(); //監聽獲得當前主題 this.settings.getActiveTheme().subscribe(val=>{ this.selectedTheme = val; }); } presentLoginModal() { const modal = this.modalCtrl.create(LoginPage); modal.onDidDismiss(()=>{ this.loadUserPage(); }) modal.present(); } //ionic生命週期方法:當頁面進入完成後呼叫 ionViewDidEnter() { this.loadUserPage(); } //載入使用者資訊 loadUserPage() { this.storage.get('token').then((val)=>{ if(val!=null){ this.isLogined = true; let loading = super.showLoading(this.loadingCtrl,"Loading..."); setTimeout(()=>{ this.avatarUrl = "../../assets/imgs/avatar.jpg"+"?"+(new Date()); this.userName = "Jack"; loading.dismiss(); },2000); }else{ this.isLogined = false; } }) } //跳轉到使用者詳情頁面 editUserInfo() { this.navCtrl.push(UserPage); } //跳轉到資料列表頁面 gotoDataList(type) { this.navCtrl.push(UserdatalistPage,{"dataType":type}); } //切換主題 toggleChangeTheme() { if(this.selectedTheme === 'dark-theme'){ this.settings.setActiveTheme('light-theme'); }else{ this.settings.setActiveTheme('dark-theme'); } } }
-
more.html
<ion-header> <ion-navbar> <ion-title>更多</ion-title> </ion-navbar> </ion-header> <ion-content> <div *ngIf="!isLogined"> <ion-card> <ion-card-header text-center> Log in 'Free Skin' and experience more features... </ion-card-header> <ion-card-content text-center> <button ion-button outline (click)="presentLoginModal()"> Sign in / Sign up </button> </ion-card-content> </ion-card> </div> <div *ngIf="isLogined"> <ion-list class="marginTop0px"> <button ion-item (click)="editUserInfo()"> <ion-avatar item-start> <img [src]="avatarUrl"> </ion-avatar> <h2> {{userName}} </h2> <p>Click to edit your user info</p> </button> </ion-list> <ion-list class="marginTop10px"> <ion-list-header> 我的資訊 </ion-list-header> <button ion-item (click)="gotoDataList('question')"> <!-- 使用color屬性也可以給icon新增顏色,color中的值在theme中定義,可以直接給定顏色 --> <ion-icon name="paper" item-start color="primary"></ion-icon> <ion-label>我的直播</ion-label> </button> <button ion-item (click)="gotoDataList('favourite')"> <ion-icon name="star" item-start color="orange"></ion-icon> <ion-label>我的關注</ion-label> </button> <button ion-item (click)="gotoDataList('answer')"> <ion-icon name="disc" item-start color="secondary"></ion-icon> <ion-label>我的護膚</ion-label> </button> </ion-list> <ion-list class="marginTop10px"> <ion-list-header> 個人設定 </ion-list-header> <ion-item> <ion-icon name="cloudy-night" item-start color="purple"></ion-icon> <ion-label>夜間模式</ion-label> <!-- 左右切換小按鈕 --> <ion-toggle color="purple" (ionChange)="toggleChangeTheme()"></ion-toggle> </ion-item> </ion-list> </div> </ion-content>