hifive と Onsen UIを組み合わせてスマートフォン/タブレット向けのUIを簡単に実現する(タブ & ナビゲーション)
Onsen UIというモバイルアプリ向けのUIフレームワークがあります。HTML5とJavaScript、CSSを使ってスマートフォンアプリを作るハイブリッドアプリ用のUIフレームワークになります。UIをネイティブアプリ風にしてくれるのはもちろん、画面のスワイプであったり、リスト表示などをネイティブアプリ風の操作にしてくれます。
そんなOnsen UIをhifiveと組み合わせて使う方法を紹介します。今回はタブバーとナビゲーションを組み合わせた使い方を紹介します。
利用するソフトウェア/ライブラリ
- Bower
- hifive
- Onsen UI
- jQuery
インストール
まず各ライブラリをインストールします。インストールはBowerを使って行います。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ bower install hifive jquery onsenui –save |
今回は .bowerrc
という設定ファイルを作成し、ライブラリのインストール先を指定しています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"directory": "public/components" | |
} |
index.htmlの作成
次に public/index.html
を作成します。タブバーを定義します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | |
<title></title> | |
<meta charset="utf-8" /> | |
<meta name="description" content="" /> | |
<meta name="author" content="" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<link rel="stylesheet" href="components/onsenui/css/onsenui.min.css" /> | |
<link rel="stylesheet" href="components/onsenui/css/onsen-css-components.min.css" /> | |
<!–[if lt IE 9]> | |
<script src="//cdn.jsdelivr.net/html5shiv/3.7.2/html5shiv.min.js"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script> | |
<![endif]–> | |
<link rel="shortcut icon" href="" /> | |
</head> | |
<body> | |
<ons-page> | |
<ons-toolbar id="toolbar"> | |
<div class="center">メイン</div> | |
</ons-toolbar> | |
<ons-tabbar swipeable position="auto" id="tabbar"> | |
<ons-tab page="tab1.html" label="Tab 1" icon="ion-home, material:md-home" badge="7" active> | |
</ons-tab> | |
<ons-tab page="tab2.html" label="Tab 2" icon="md-settings" active-icon="md-face"> | |
</ons-tab> | |
</ons-tabbar> | |
</ons-page> | |
<script src="components/onsenui/js/onsenui.js"></script> | |
<script src="components/jquery/dist/jquery.min.js"></script> | |
<script src="components/hifive/ejs-h5mod.js"></script> | |
<script src="components/hifive/h5.dev.js"></script> | |
<script src="js/app.js"></script> | |
</body> | |
</html> |
タブバーの画面
まず最初に表示される tab1.html の画面を用意します。タブ1の中身でナビゲーションを行いますので、ここではナビゲーションだけを定義します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ons-page id="tab1"> | |
<ons-navigator swipeable id="tab1nav" page="tab1-main.html"></ons-navigator> | |
</ons-page> |
そして最初に表示するのは tab1-main.html です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ons-page id="tab1main"> | |
<p style="text-align: center;"> | |
<p>ここはメインページです。</p> | |
<p> | |
<ons-input id="message" modifier="underbar" placeholder="メッセージ" float></ons-input> | |
</p> | |
<ons-button class="btn" modifier="large">詳細画面に移動</ons-button> | |
</p> | |
</ons-page> |
JavaScriptの実装
まずメイン画面でボタンを押したら詳細画面に移動する部分を作ります。 tab1MainController
を定義します。そしてナビゲーションのpushPageを使って画面遷移します。
ここでヘッダー部の文字を詳細に変えるようにイベントを設定します。コントローラのトリガーを使います。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ons-page id="tab1main"> | |
<p style="text-align: center;"> | |
<p>ここはメインページです。</p> | |
<p> | |
<ons-input id="message" modifier="underbar" placeholder="メッセージ" float></ons-input> | |
</p> | |
<ons-button class="btn" modifier="large">詳細画面に移動</ons-button> | |
</p> | |
<script> | |
ons.getScriptPage().onInit = function() { | |
const tab1MainController = { | |
__name: 'Tab1MainController', | |
'.btn click'() { | |
this.trigger('changeTitle', { | |
back: true, | |
title: '詳細' | |
}); | |
$('#tab1nav')[0].pushPage('tab1-detail.html', { | |
message: this.$find('#message').val() | |
}); | |
} | |
}; | |
h5.core.controller('#tab1main', tab1MainController); | |
} | |
</script> | |
</ons-page> |
トリガーは js/app.js
内に定義する全体のコントローラに実装します。 {rootElement} changeTitle
でイベントを受け取ることができます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const appController = { | |
__name: 'AppController', | |
_tab1Controller: Tab1Controller, | |
_tab2Controller: Tab2Controller, | |
__ready() { | |
}, | |
'{rootElement} changeTitle'(context) { | |
let back = ''; | |
if (context.evArg.back) { | |
back = `<div class="left"> | |
<ons-back-button id="backButton">Back</ons-back-button> | |
</div>`; | |
} | |
const outerHTML = ons.createElement(` | |
<ons-toolbar id="toolbar"> | |
${back} | |
<div class="center">${context.evArg.title}</div> | |
</ons-toolbar> | |
`); | |
this.$find('#toolbar').prop('outerHTML', outerHTML.outerHTML); | |
}, | |
'#tabbar prechange'() { | |
this.trigger('changeTitle', { | |
title: "メイン", | |
back: false | |
}); | |
} | |
}; | |
h5.core.controller('body', appController); |
なお、 Tab1Controller と Tab2Controller は別な画面に定義されています。そのため、変数が定義されているかどうかを確認する必要があります。今回は以下のような仕組みで回避しています。変数があるかどうか調べて、なければ100ms待って変数の確認をしています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ons.ready(() => { | |
resolveVariable(['Tab1Controller', 'Tab2Controller']) | |
.then(() => { | |
// 変数定義済み | |
}); | |
}); | |
const resolveVariable = (ary) => { | |
return new Promise((res, rej) => { | |
setTimeout(() => { | |
let bol = true; | |
for (let index in ary) { | |
if (!(ary[index] in window)) { | |
bol = false; | |
return resolveVariable(ary) | |
} | |
} | |
if (bol) res(); | |
}, 100); | |
}) | |
} |
画面遷移を戻る
詳細画面に移動したら、逆に戻ってくる処理を作ります。これは tab1-detail.html に実装します。こちらでもトリガーを使っています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ons-page id="tab1detail"> | |
<p style="text-align: center;"> | |
こちらは詳細画面です | |
<ons-button class="btn" modifier="large">戻る</ons-button> | |
</p> | |
<script> | |
ons.getScriptPage().onInit = function() { | |
const tab1DetailController = { | |
__name: 'Tab1DetailController', | |
'.btn click'() { | |
this.trigger('changeTitle', { | |
back: false, | |
title: 'メイン' | |
}); | |
$('#tab1nav')[0].popPage(); | |
} | |
}; | |
h5.core.controller('#tab1detail', tab1DetailController); | |
} | |
</script> | |
</ons-page> |
ここまでの処理でタブバーとナビゲーションバーを組み合わせた処理が実現します。
タブバーとナビゲーションバーを組み合わせた動きはスマートフォンアプリでよくある実装だと思います。hifiveのコントローラ連携を使うことで、機能を画面毎に分けつつ、分かりやすい実装が実現します。
コードはhifiveWithOnsenUI/tabbar_navigation at master · hifivemania/hifiveWithOnsenUIにアップロードされています。実装時の参考にしてください。
コメントは受け付けていません。