Hatena::ブログ(Diary)

bufferings

2011-05-12

#GWT & Eclipseでモバイル用のすげーWebアプリ開発

| 19:57 |

Using #GWT and Eclipse to Build Great Mobile Web Apps

モバイルデバイス

  • 画面が小さい
  • 縦向きと横向きがある
  • 処理が遅い
  • オフラインになりうる

解決策

GWT & GPE

もう言うまでもないけどサイトは英語版見ないとだめです。日本語版は参考程度に。

サンプルアプリ: Cloud Tasks


ソースはこれかな?

どんなフォームファクターに対してもすごいUIを作る

フォームファクタ

UiBinderで宣言的に書ける

例えばこんな感じ。宣言的。

Google Code Archive - Long-term storage for Google Code Project Hosting.から抜粋

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder
  xmlns:ui="urn:ui:com.google.gwt.uibinder"
  xmlns:g="urn:import:com.google.gwt.user.client.ui"
  xmlns:app="urn:import:com.google.gwt.sample.mobilewebapp.client.ui">

  <ui:style>
    .outer {
      background: #eee;
    }
    
    .title {
      background: #393939;
      color: white;
      padding: 4px 10px;
      font-size: 20pt;
    }
  </ui:style>

  <g:DockLayoutPanel unit="PT">
    <!-- Title. -->
    <g:north size="28">
      <g:Label addStyleNames="{style.title}">DETAILS</g:Label>
    </g:north>

    <g:center>
      <g:ScrollPanel addStyleNames="{style.outer}">
        <g:HTMLPanel>
          <!-- Edit Form. -->
          <div class="{style.editForm}">
            <!-- Task name. -->
            <div class="{style.label}">What</div>
            <div class="{style.textBoxWrapper}">
              <g:Label addStyleNames="{style.field} {style.nameBox}" ui:field="nameEditor" />
            </div>
        </g:HTMLPanel>
      </g:ScrollPanel>
    </g:center>
  </g:DockLayoutPanel>

</ui:UiBinder>

WYSIWYGGWT Designerで開発スピードアップ

GPEについてるやつ。まだ使ったことないけど、VisualStudioみたいだね。

Error 404 (Not Found)!!1

f:id:bufferings:20110512180746p:image

ユーザー体験の最適化

遅延バインディングフォームファクターごとに異なる実装を適用

Google Code Archive - Long-term storage for Google Code Project Hosting.から抜粋

  <!-- 例:モバイルの場合 -->
  <replace-with class="com.google.gwt.sample.mobilewebapp.client.ClientFactoryImplMobile">
    <when-type-is class="com.google.gwt.sample.mobilewebapp.client.ClientFactory"/>
    <!-- ココ -->
    <when-property-is name="formfactor" value="mobile"/>
  </replace-with>

formfactorが"tablet"の場合はタブレット用の実装を使うようにするなど。


formfactorはCDATAjs使ってUAをチェックしてるようです。

Google Code Archive - Long-term storage for Google Code Project Hosting.から抜粋

  <property-provider name="formfactor">
  <![CDATA[
      // URLから取得(省略)

      // URLになければUAから取得
      var ua = navigator.userAgent.toLowerCase();
      if (ua.indexOf("iphone") != -1 || ua.indexOf("ipod") != -1) {
        // iphone and ipod.
        return "mobile";
      } else if (ua.indexOf("ipad") != -1) {
        // ipad.
        return "tablet";
      } else if (ua.indexOf("android") != -1 || ua.indexOf("mobile") != -1) {
        /*
         * Android - determine the form factor of android devices based on the diagonal screen
         * size. Anything under six inches is a phone, anything over six inches is a tablet.
         */
        var dpi = 160;
        var width = $wnd.screen.width / dpi;
        var height = $wnd.screen.height / dpi;
        var size = Math.sqrt(width*width + height*height);
        return (size < 6) ? "mobile" : "tablet";
      }
      
      // Everything else is a desktop.
      return "desktop";
  ]]>
  </property-provider>

Landscape vs Portrait

次のようなインターフェイスで向きの変更を検知

Google Code Archive - Long-term storage for Google Code Project Hosting.から抜粋

public interface OrientationHelper {
  boolean isPortrait();

  HandlerRegistration setCommands(HasAttachHandlers widget, Command forPortrait,
      Command forLandscape);
}

実装はこんな感じ。

Google Code Archive - Long-term storage for Google Code Project Hosting.から抜粋

  private static boolean calculateIsPortrait() {
    return Window.getClientHeight() > Window.getClientWidth();
  }

calculateIsPortraitで縦と横の長さみてるのね。


そしてWindowのリサイズイベントでコマンド発火か。なる。

  public WindowBasedOrientationHelper() {
    isPortrait = calculateIsPortrait();
    windowResizeReg = Window.addResizeHandler(new ResizeHandler() {
      public void onResize(ResizeEvent event) {
        update();
      }
    });
  }

  private void update() {
    boolean was = isPortrait;
    isPortrait = calculateIsPortrait();
    if (was != isPortrait) {
      for (CommandSet helper : commandSets) {
        helper.fire();
      }
    }
  }
}

使うときはこんな感じ

Google Code Archive - Long-term storage for Google Code Project Hosting.から抜粋

    orientationHelper.setCommands(this, new Command() {
      @Override
      public void execute() {
        onShiftToPortrait();
      }
    }, new Command() {
      @Override
      public void execute() {
        onShiftToLandscape();
      }
    });

Icing on the cake

Icing on the cake: 「あれば便利だから、ぜひやろう」か。へぇ。icing on the cake - 誰も教えてくれなかったIT英語

MVPでコードを最大限再利用しまそ。て話。



きびきびさせるぞー


Demo

コネクションなくても動くように

オフラインでも動くようにLocalStorageを使おうという話。

GWT 2.4 SDKをチェックしてね :-)」だって。

雑感

GWTで何か作りたくなった。使うなら2.4だなー。

トラックバック - http://d.hatena.ne.jp/bufferings/20110512/1305197877
リンク元
Connection: close