「引き下げて更新」する機能を Dojo Mobile を使用して実装する

スマートフォンのネイティブ・アプリケーションでよく使用される UI パターンを実装する

モバイル Web アプリケーションでよく使用される「引き下げて更新」する機能を、Dojo Mobile 1.8 を使用して実装する方法を学びましょう。この記事では、2 つのサンプル・アプリケーションを作成する方法について説明します。1 つは引き下げて更新するアプリケーション、もう 1 つはそれを変形した、引き下げて戻るアプリケーションです。記事で取り上げるすべてのソース・コードはダウンロード可能な形で提供してあります。これらのサンプル・アプリケーションの作成方法を学べば、この UI パターンのさまざまなバリエーションを実装できるようになります。

Yoshiroh Kamiyama (kami@jp.ibm.com), Software Engineer, IBM

Photo of Yoshiroh Kamiyama神山淑朗はソフトウェア開発研究所のアドバイザリー・ソフトウェア開発エンジニアです。Rational Portfolio Manager、Lotus iNotes、Mobile MashupなどいくつかのDojoベースの開発プロジェクトを経て、2011年からはWebSphere Feature Pack for Web 2.0 and Mobileの開発に従事しています。Dojo Mobileのコントリビューターであり、Dojoツールキットのコミッターとして活動しています。



2012年 12月 13日

「引き下げて更新」は、iPhone、Android、BlackBerry などのスマートフォンのネイティブ・アプリケーションで広く使用されている UI パターンです。この UI パターンは、その名前が示すとおりのことを実行します。つまり、リストの先頭が表示された状態で、リストを指で引き下げ、その指を離すと、そのリストの内容が更新されます。この動作の様子を図 1 に示します。この一般的な機能により、ユーザーは素早くビューを更新することができます。

図 1. 引き下げて更新する
iOS アプリケーションで引き下げて更新する機能を 3 つのスクリーン・ショットで説明しています。

この記事では、Dojo Mobile 1.8 を使用して、引き下げて更新する機能をアプリケーションに実装する方法について説明します。まず、ユーザーがビューを引き下げると画面の上部にメッセージ・ボックスが現れる簡単なウィジェットを作成します。次に、そのウィジェットを使用して 2 つのサンプル・アプリケーションを作成します。1 つは引き下げて更新するアプリケーション、もう 1 つは引き下げて戻るアプリケーションです。(この記事の終わりにある「ダウンロード」セクションから完全なソース・コードを入手してください。)

PullView ウィジェットを作成する

図 1 や、皆さんが使用しているスマートフォンのネイティブ・アプリケーションを見るとわかるように、スマートフォンの画面でリストを指で引き下げると、先頭のヘッダーは位置が固定されたまま、メッセージ・ボックス (「Pull down to refresh... (引き下げて更新…)」などのメッセージが表示される領域) とリスト・コンポーネントが一緒に動きます。この動作を Dojo Mobile を使用して実現する 1 つの方法をリスト 1 に示します。

リスト 1. ScrollableView にメッセージ・ボックスを配置する
<h1 data-dojo-type="dojox.mobile.Heading"
    data-dojo-props='fixed:"top"'>Technical Topics</h1>
<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
  <div id="pull">
    <img id="icon" src="images/refresh-arrow.png">
    <div id="msg1">Pull down to refresh...</div>
    <div id="msg2">Check for new items</div>
  </div>
  <ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList">
    ....
  </ul>
</div>

リスト 1 では、Heading ウィジェットを使用して画面上部にヘッダーを配置しています。メッセージ・ボックスとリストは ScrollableView ウィジェットの中にあります。こうすることで、ヘッダーは固定されたまま、メッセージ・ボックスとリストが一緒にスクロールするようになります。ただし、メッセージ・ボックスは最初から表示された状態になります (図 2)。

図 2. ScrollableView 内のメッセージ・ボックス
ScrollableView 内のメッセージ・ボックスのスクリーン・ショット

ユーザーがリストを引き下げるまではメッセージ・ボックスを表示したくないので、メッセージ・ボックスを最初は非表示にするための方法が必要です。

メッセージ・ボックスを非表示にする

メッセージ・ボックスの位置を変更する CSS を適用すると、メッセージ・ボックスを非表示にすることができます (リスト 2)。

リスト 2. リストの先頭にあるメッセージ・ボックスを非表示にする
#pull {
  position: absolute;
  height: 65px;
  top: -65px;
}

リスト 2 では、リストより上の絶対位置をメッセージ・ボックスに対して指定することで、メッセージ・ボックスを非表示にしています。ユーザーがリストを引き下げると、メッセージ・ボックスが表示されます。

メッセージ・ボックスを表示したままにする

現時点では、リストが引き下げられた時のみメッセージ・ボックスが表示されます。ここまでは順調ですが、ユーザーがリストから指を離した途端に ScrollableView が最初の位置に戻ってしまうという問題があります。ユーザーがリストから指を離しても、リストの更新中はメッセージ・ボックスを表示したままにする必要があります。この動作を実現するには、ScrollableView をサブクラス化して、必要なロジックを実装します。そのロジックを実装するのに適しているのは、adjustDestination() メソッドです。このメソッドは、メッセージ・ボックスの縦位置を取得し、画面上部にメッセージ・ボックス全体が表示されるところまでメッセージ・ボックスをスライドさせます。adjustDestination()false を返した場合には、デフォルトのスクロール動作が実行されなくなります。このサブクラスのサンプル・コードをリスト 3 に示します。

リスト 3. メッセージ・ボックスを表示したままにする (PullView.js)
define([
  "dojo/_base/declare",
  "dojo/dom",
  "./ScrollableView"
], function(declare, dom, ScrollableView){
  return declare("dojox.mobile.PullView", ScrollableView, {
    adjustDestination: function(to, pos, dim){
      var h = dom.byId("pull").offsetHeight;
      if(this.getPos().y >= h){ // if completely revealed
        this.slideTo({y:h}, 0.3, "ease-out");
        return false;
      }
      return true;
    }
  });
});

イベントを公開する

最後に、ユーザー・アプリケーションがイベントをリッスンしたり、イベントに接続したりできるように、イベントを公開する必要があります (リスト 4)。

リスト 4. イベントを公開する (PullView.js)
  return declare("dojox.mobile.PullView", ScrollableView, {
    adjustDestination: function(to, pos, dim){
      var h = dom.byId("pull").offsetHeight;
      if(this.getPos().y >= h){
        this.slideTo({y:h}, 0.3, "ease-out");
        connect.publish("/dojox/mobile/onPulled", [this]);
        this.onPulled(this);
        return false;
      }
      return true;
    },


    scrollTo: function(/*Object*/to, /*Boolean?*/doNotMoveScrollBar, /*DomNode?*/node){
      this.inherited(arguments); // scrollable#scrollTo() will be called
      var h = dom.byId("pull").offsetHeight;
      connect.publish("/dojox/mobile/onPull", [this, to.y, h]);
      this.onPull(this, to.y, h);
    },

    onPull: function(/*Widget*/view, /*Number*/y, /*Number*/h){
    },

    onPulled: function(/*Widget*/view){
    }
  });

リスト 4 では、メッセージ・ボックスが引き下げられている間は onPull() が呼び出されます。メッセージ・ボックスが完全に引き下げられて、指が離されると onPulled() が呼び出されます。


引き下げて更新するアプリケーションを作成する

PullView ウィジェットを作成できたので、引き下げて更新するサンプル・アプリケーションを作成する準備が整いました。最初のステップでは、リスト 1リスト 5 のように書き直します。

リスト 5. 引き下げて更新するサンプル・アプリケーション
<h1 data-dojo-type="dojox.mobile.Heading"
    data-dojo-props='fixed:"top"'>Technical Topics</h1>
<div id="view1" data-dojo-type="dojox.mobile.PullView"
    data-dojo-props='onPull:onPull, onPulled:onPulled'>
  <div id="pull">
    <div id="prog" class="progDiv"></div>
    <img id="icon" src="images/refresh-arrow.png">
    <div id="msg1"></div>
    <div id="msg2">Check for new items</div>
  </div>
  <ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList">
    ....
  </ul>
</div>

次に、アプリケーションにもう少し動作を追加する必要があります。

矢印アイコンを回転させる

リストが引き下げられた状態の間、矢印アイコンを回転させてみたいと思います (図 3)。

図 3. リストが引き下げられた状態の間、矢印アイコンを回転させる
回転する矢印アイコンがメッセージ・ボックスのメッセージの隣に表示された状態のスクリーン・ショット

リスト 6 を見るとわかるように、onPull() ハンドラーで矢印アイコンを回転させることができます。また、onPull() の中でメッセージを更新し、リストから指を離すようにユーザーに伝えることもできます。

リスト 6. 矢印アイコンを回転させる
onPull = function(view, y, h){
  dom.byId("msg1").innerHTML = percent < 100 ?
    "Pull down to refresh..." : "Release to refresh...";
  y = y > h ? h : y;
  var percent = y / h * 100;
  var deg = -1.8 * percent + 360;
  dom.byId("icon").style.webkitTransform = "rotate(" + deg + "deg)";
}

アクションを実行する

メッセージ・ボックスが完全に引き下げられて、指が離されると、onPulled() ハンドラーが呼び出されます。このハンドラーに更新アクションを含めることができます。含めるアクションは、アプリケーションによって異なるものにすることができます。リスト 7 では、setStore() を呼び出すことで、リスト・ウィジェットがリストの内容を更新しています。

リスト 7. リストの内容を更新する
onPulled = function(view){
  if(prog1.timer){ return; }

  // hide the arrow icon
  dom.byId("icon").style.visibility = "hidden";

  // update the message
  dom.byId("msg1").innerHTML = "Loading...";

  // add a ProgressIndicator and start it
  dom.byId("prog").appendChild(prog1.domNode);
  prog1.start();

  // reload the datastore
  store.close();
  registry.byId("list").setStore(store);
}

さらにリスト 7 では、矢印アイコンを非表示にし、メッセージを「Loading... (更新中…)」に変更して、ProgressIndicator ウィジェットを追加しています。リストの内容を更新中のリスト・ビューを図 4 に示します。

図 4. リストの内容を更新する
リストの内容を更新中のリスト・ビューのスクリーン・ショット

メッセージ・ボックスを閉じる

更新アクションが完了したら、リスト 8 のようにメッセージ・ボックスを閉じます。

リスト 8. メッセージ・ボックスを閉じる
connect.connect(registry.byId("list"), "onComplete", function(){
    registry.byId("view1").slideTo({y:0}, 0.3, "ease-out");
    prog1.stop();
    dom.byId("icon").style.visibility = "visible";
});

メッセージ・ボックスが閉じられ、リストの内容が更新された状態のリスト・ビューを図 5 に示します。

図 5. メッセージ・ボックスが閉じられた状態
メッセージ・ボックスが閉じられ、リストの内容が更新された状態のリスト・ビューのスクリーン・ショット

引き下げて戻るアプリケーションを作成する

今度はサンプル・アプリケーションのバリエーションとして、「引き下げて戻る」アプリケーションを作成します。ユーザーがコンテンツを引き下げると、横長の細い枠が表示され、その中を緑色の短いバーが右から左へと移動します (図 6)。

図 6. 引き下げて戻るアプリケーション
引き下げて戻るアプリケーションの 2 つのスクリーン・ショットが示されています。左側のスクリーン・ショットは、ユーザーがコンテンツを引き下げるところを示しています。右側のスクリーン・ショットは、コンテンツが引き下げられているときに、横長の細い枠とその中の緑色の短いバーが表示されている様子を示しています。

緑色の短いバーが横長の枠の左端に達した後で、ユーザーがコンテンツから指を離すと (図 7)、アプリケーションは前のビューに戻ります。

図 7. 前のビューに戻る直前の状態
引き下げて戻るアプリケーションのスクリーン・ショットとして、緑色の短いバーが横長の枠の左端に達したときにユーザーがコンテンツから指を離すと前のビューに戻る様子を示しています。

緑色の短いバーをスライドさせる

最初のサンプル・アプリケーションで onPull() ハンドラーを使用して矢印アイコンの回転を実装したのと同じように、onPull() で短いバーをスライドさせることができます (リスト 9)。

リスト 9. 緑色の短いバーをスライドさせる
onPull = function(view, y, h){
  dom.byId("msg1").innerHTML = y < h ? "Pull down to go back" : "Go back";
  y = y > h ? h : y;
  var percent = Math.round(y / h * 100);
  dom.byId("knob").style.left = (100 - percent) + "px";
}

アクションを実行する

この場合に onPulled() ハンドラーの中で実行するアクションは、現在のビューの performTransition() メソッドを使用して前のビューに戻ることです (リスト 10)。

リスト 10. 前のビューに戻る
onPulled = function(view){
  registry.byId("view2").performTransition("view1", -1, "slide");
}

まとめ

この記事では、引き下げて更新する UI パターンの 2 つのバリエーションを Dojo Mobile 1.8 を使用して実装する方法について学びました。これで皆さんも、引き下げて「何か」を実行するアプリケーションを実装できるはずです (「何か」とは皆さんが選択したアクションです)。

この記事で説明した PullView ウィジェットの実装よりも、コード・サンプルで実際に実装した PullView ウィジェットの方が少し複雑であることに注意してください。コード・サンプルでは、pullDir="up" オプションを指定してメッセージ・ボックスをビューの一番下に配置することもできます。このオプションにより、例えば「引き上げてさらに読み込む」アプリケーションを作成することができます。


ダウンロード

内容ファイル名サイズ
PullView widget and sample appspullview.zip16KB

参考文献

学ぶために

製品や技術を入手するために

  • Dojo 1.8.x: 最新バージョンの Dojo Toolkit をダウンロードしてください。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Mobile development
ArticleID=848736
ArticleTitle=「引き下げて更新」する機能を Dojo Mobile を使用して実装する
publish-date=12132012