The sky is the limit

ハイブリッドアプリ開発、PWAなど効率の良いiOSアプリ、Androidアプリ開発の情報を共有したい。アプリ開発は楽しい。【PWA、AngularJS、Monaca、Cordova、OnsenUI】

1-1【UI開発】OnsenUIを使ったページ遷移の実装1 【tabbar編】- 【連載】ハイブリッドアプリ開発で貯金管理アプリを作る【Cordova・Monaca・OnsenUI・AngularJS】 -

【連載】ハイブリッドアプリ開発で貯金管理アプリを作る【Cordova・Monaca・OnsenUI・AngularJS】

f:id:duo-taro100:20160218004611p:plain

1章 UI開発

1-1【UI開発】OnsenUIを使ったページ遷移の実装1 【tabbar編】


このページは、過去の記事

www.sky-limit-future.com

を最新化したもの。
はてなブログにはブログの記法が何種類かあって、一旦それで書くと、他の記法に変更することができない。以前のままだと、ソースコードの表示があまり行けてなかったので、記法を変えたかった。なので、新しい記事として新規作成した。内容も結構変わっている。前よりも細く。


今回から「【連載】ハイブリッドアプリ開発で貯金管理アプリを作る【Cordova・Monaca・OnsenUI・AngularJS】」の実装について書いていく。

www.sky-limit-future.com

このページで今後の掲載予定を書いている通り、最初の数回はUIの実装について。
今回は「OnsenUIを使ったページ遷移の実装1 【tabbar編】」について。

OnsenUIを使ったページ遷移は大きく分けて次の4つがある。

■ナビゲーション型
■スライディングメニュー型
■タブバー型
■スプリットビュー型
それぞれの詳細はこちらから。
本連載で作成するアプリは大きな画面間での遷移にはタブバー型を使用し、それぞれの大きな画面から小画面へ遷移するときはナビゲーション型での遷移も使用しているので、その2つを説明していく。

タブバー型画面遷移

以下、OnsenUIのドキュメントから引用

iPhoneやiPadアプリでよく見られ、ページの下部にタブバーを配置したパターンになります。通常、タブバーにはいくつかの項目(アイテム)が並び、アイコンとテキストで表現されます。複数の機能を提供したいような場合に用いられます。Onsen UIでタブバーを実装するには、コンポーネントを使用します。

Learn How to Use - Onsen UI Framework v1 - Onsen UI


実装は以下の通り。
ちなみにSPA(Single Page Application)を導入しているため、htmlはindex.htmlのみとなっている。
SPAについてはこちらが非常にわかりやすい。

www.oro.com

まずは動きから

www.youtube.com

◆index.html
この状態だと、tabを使用した移動とtabを強制的に変更する画面遷移はうまくいくが、navigatorを使用した場合、画面遷移先から元の画面に戻ることができない。この原因は次回のナビゲーション型画面遷移で詳しく。
コード下部にはscriptタグでangularのmodule定義と、画面遷移用のコントローラを用意している。

    <!-- 共通ページ -->
    <ons-navigator var="myNavigator">
        <ons-page ng-controller="pageCtrl as pctrl">
           <ons-toolbar id="toolbar">
              <div class="center">{{pctrl.title}}</div>
                <!-- 一覧ページから詳細ページへの遷移ボタンを実装 -->
              <div class="right" ng-if="pctrl.title == '一覧'">
                    <ons-button ng-click="myNavigator.pushPage('listDetail.html');">詳細画面へ</ons-button>
                </div>
            </ons-toolbar>

            <ons-tabbar position="bottom">
                <ons-tab page="home.html" label="ホーム" icon="home" active></ons-tab>
                <ons-tab page="list.html" label="一覧" icon="list"></ons-tab>
                <ons-tab page="history.html" label="履歴" icon="history"></ons-tab>
                <ons-tab page="simulation.html" label="計算" icon="calculator"></ons-tab>
                <ons-tab page="config.html" label="設定" icon="gear"></ons-tab>
            </ons-tabbar>
        </ons-page>
    </ons-navigator>

    <!-- ホーム画面 -->
    <ons-template id="home.html">
        <ons-page id="homePage" ons-show="pctrl.title = 'ホーム'">
            <div class="content" ng-app="myApp">
                <div class="main">
                    <ons-button ng-click="pctrl.changeConfigTab()">設定画面へ</ons-button>
                </div>
            </div>
        </ons-page>
    </ons-template>

    <!-- 一覧画面 -->
    <ons-template id="list.html">
        <ons-page id="listPage" ons-show="pctrl.title = '一覧'">
            <div class="content" ng-app="myApp">
                <div class="main">
                    <ons-button ng-click="myNavigator.pushPage('listDetail.html');">詳細画面へ</ons-button>
                </div>
            </div>
        </ons-page>
    </ons-template>

    <!-- 詳細画面画面 -->
    <ons-template id="listDetail.html">
        <ons-page id="detailPage" ons-show="pctrl.title = '詳細'">
            <div class="content" ng-app="myApp">
                <div class="main">
                    <p>詳細画面</p>
                </div>
            </div>
        </ons-page>
    </ons-template>

    <!-- 編集画面 -->
    <ons-template id="listEdit.html">
        <ons-page id="editPage" ons-show="pctrl.title = '編集'">
            <div class="content" ng-app="myApp">
                <div class="main">
                    <p>編集画面</p>
                </div>
            </div>
        </ons-page>
    </ons-template>

    <!-- 履歴画面 -->
    <ons-template id="history.html">
        <ons-page id="historyPage" ons-show="pctrl.title = '履歴'">
            <div class="content" ng-app="myApp">
                <div class="main">
                    <ons-button ng-click="myNavigator.pushPage('chart.html');">グラフ画面へ</ons-button>
                </div>
            </div>
        </ons-page>
    </ons-template>

    <!-- グラフ画面 -->
    <ons-template id="chart.html">
        <ons-page id="chartPage" ons-show="pctrl.title = 'グラフ'">
            <div class="content" ng-app="myApp">
                <div class="main">
                    <p>グラフ画面</p>
                </div>
            </div>
        </ons-page>
    </ons-template>

    <!-- 計算画面 -->
    <ons-template id="simulation.html">
        <ons-page id="simPage" ons-show="pctrl.title = '計算'">
            <div class="content" ng-app="myApp">
                <div class="main">
                    <p>計算画面</p>
                </div>
            </div>
        </ons-page>
    </ons-template>

    <!-- 設定画面 -->
    <ons-template id="config.html">
        <ons-page id="configPage" ons-show="pctrl.title = '設定'">
            <div class="content" ng-app="myApp">
                <div class="main">
                    <p>設定画面</p>
                </div>
            </div>
        </ons-page>
    </ons-template>
<script>
    // モジュールの定義
    var myApp = ons.bootstrap('myApp',[]);

    /**
     * 画面遷移用コントローラ
     */ 
    myApp.controller('pageCtrl', function() {

        // タブバーを取得
        var tabbar = document.querySelector("ons-tabbar");

        // 1つ目のタブへ遷移
        this.changeHomeTab = function(){
            tabbar.setActiveTab(0);
        };
        // 2つ目のタブへ遷移
        this.changeListTab = function(){
            tabbar.setActiveTab(1);
        }
        // 3つ目のタブへ遷移
        this.changeHistoryTab = function(){
            tabbar.setActiveTab(2);
        }
        // 4つ目のタブへ遷移
        this.changeSimTab = function(){
            tabbar.setActiveTab(3);
        }
        // 5つ目のタブへ遷移
        this.changeConfigTab = function(){
            tabbar.setActiveTab(4);
        }
    });
</script>

ちょっと量が多いので、細く分割して説明する。

◆共通ページについて

<!-- 共通ページ -->
<ons-navigator var="myNavigator">
    <ons-page ng-controller="pageCtrl as pctrl">
       <ons-toolbar id="toolbar">
          <div class="center">{{pctrl.title}}</div>
            <!-- 一覧ページから詳細ページへの遷移ボタンを実装 -->
          <div class="right" ng-if="pctrl.title == '一覧'">
                <ons-button ng-click="myNavigator.pushPage('listDetail.html');">詳細画面へ</ons-button>
            </div>
        </ons-toolbar>

        <ons-tabbar position="bottom">
            <ons-tab page="home.html" label="ホーム" icon="home" active></ons-tab>
            <ons-tab page="list.html" label="一覧" icon="list"></ons-tab>
            <ons-tab page="history.html" label="履歴" icon="history"></ons-tab>
            <ons-tab page="simulation.html" label="計算" icon="calculator"></ons-tab>
            <ons-tab page="config.html" label="設定" icon="gear"></ons-tab>
        </ons-tabbar>
    </ons-page>
</ons-navigator>

この部分は、tabbarの機能によって移動した場合の画面の共通箇所。
ons-tabタグのpage属性に指定したページで、共通画面として使われる。
逆に、page属性に指定のないページでは、使用されない箇所。
ons-navigatorタグについては後ほど説明。

ons-toolbar

ページのタイトルや、画面遷移用のボタンを設置している。
ページタイトルが「一覧」の場合のみ、toolarの右側にボタンが表示されるような実装。
androidとiosでタイトルの表示位置が異なる。androidは左寄り、iosは中央。
onsenUI v1には「fixed-style」というoptionがあって、これを使えばandroidも中央配置ができたが、onsenUI v2ではなくなったぽい。
あとで出てくるが、NavigatorのpushPage()したあとのデザインが気になる。

<ons-toolbar id="toolbar">
  <div class="center">{{pctrl.title}}</div>
    <!-- 一覧ページから詳細ページへの遷移ボタンを実装 -->
  <div class="right" ng-if="pctrl.title == '一覧'">
        <ons-button ng-click="myNavigator.pushPage('listDetail.html');">詳細画面へ</ons-button>
    </div>
</ons-toolbar>

■androidはタイトルが左寄り
f:id:duo-taro100:20170825233856p:plain:w300

■一覧画面のみ、詳細画面への遷移ボタンが表示される
f:id:duo-taro100:20170825233905p:plain:w300

ons-tabbar

position属性にbottomを指定しているが、画面下部にタブ領域が表示されるoption。
androidでは指定しないと、画面上部に表示されてしまう。

ons-tabbar-itemタグに「active="true"」を付与することで、初期ページを設定できる。
page属性に指定した値は、各ons-templateタグのid属性に記載する。

<ons-tabbar position="bottom">
    <ons-tab page="home.html" label="ホーム" icon="home" active></ons-tab>
    <ons-tab page="list.html" label="一覧" icon="list"></ons-tab>
    <ons-tab page="history.html" label="履歴" icon="history"></ons-tab>
    <ons-tab page="simulation.html" label="計算" icon="calculator"></ons-tab>
    <ons-tab page="config.html" label="設定" icon="gear"></ons-tab>
</ons-tabbar>

<!-- 例えばホーム画面だったら以下のようにid属性にhome.htmlを指定 -->
<ons-template id="home.html">
    <ons-page>
    </ons-page>
</ons-template>


また、clickイベントでタブを変更したい場合は以下のように実装する。
先ほど、全体のindex.htmlを記載したが、その下部にあるscriptタグで括られている箇所。

// モジュールの定義
var myApp = ons.bootstrap('myApp',[]);

/**
 * 画面遷移用コントローラ
 */ 
myApp.controller('pageCtrl', function() {

    // タブバーを取得
    var tabbar = document.querySelector("ons-tabbar");

    // 1つ目のタブへ遷移
    this.changeHomeTab = function(){
        tabbar.setActiveTab(0);
    };
    // 2つ目のタブへ遷移
    this.changeListTab = function(){
        tabbar.setActiveTab(1);
    }
    // 3つ目のタブへ遷移
    this.changeHistoryTab = function(){
        tabbar.setActiveTab(2);
    }
    // 4つ目のタブへ遷移
    this.changeSimTab = function(){
        tabbar.setActiveTab(3);
    }
    // 5つ目のタブへ遷移
    this.changeConfigTab = function(){
        tabbar.setActiveTab(4);
    }
});

document.querySelector()でtabbarを取得して、それに対してsetActiveTab(index)を使用。
引数のindexは0から始まることに注意。今回の例で言えば、ホーム画面に行くためには

tabbar.setActiveTab(0);

とする。
※使っているJSフレームワークによって、メソッドなどが違うので注意。 詳しくはドキュメント参照

ja.onsen.io


タブバー型画面遷移はここまで。
次回はOnsenUIを使ったページ遷移の実装2【Navgator編】