メイン

2010年9月28日

DOMろうTouchコンテンツ
このエントリーをはてなブックマークに追加 このエントリーをlivedoorクリップに追加

Flashエンジニアnao ozawaです。最近あんまりゴリゴリとFlashでコーディングしていません。なんでかなぁ!まるで働いていないみたいじゃないですか。一応ちゃんと仕事してるんですよ?
まぁ、そんな感じの毎日なので、実はここ数日、作業のかたわら、スマートフォン向けページのレイアウト方法を色々考えております。

・ブラウザの画面回転するのめんどくさくね?

 みなさんご存知のように、iPhoneを筆頭に最近のスマートフォンは、携帯を横に向けると、合わせてくるりと画面が横レイアウトに変わります。()く言う私も初めてソレに遭遇したときには驚きを隠せず、暫くは日がな一日iPhoneをくりくりと縦にしたり横にしたりして過ごしていたものです。それはそれは楽しかった。
が、しかし、最近スマートフォン向けのページを作る側にまわってみて、はじめて気がついたのです。

画面の幅が変わるのって、めんどくせぇ

もう喜んでる場合じゃない。あり得ないほどめんどくさかったのです。

 そう思ったきっかけはクリッカブルマップ。懐かしい響きですね。Flashが全盛を極めてからは、みんなすっかり利用されなくなってきていますが、残念ながらiPhoneではFlashは動きません。そのため、どうしてもクリッカブルマップを使いたかったんですが、ここで問題になったのが、画面の回転なのです。
 クリッカブルマップは画像上の絶対座標によってクリックエリアを決定しています。手持ちのiPhone4では画面が回転した時も横幅の拡大は「表示」の拡大という扱いになっているため座標はズレないのですが、実はXPERIA(Android1.6)では、横表示になった時に画面の再描画が行われるため、画像が縮小されます。
 じゃぁ、初めから画像の表示サイズをピクセルで指定しておくとか、機種ごとにテンプレートを用意すればいいんじゃない?という意見もあろうかと思います。自分でもそう思います。ですが、それも面倒じゃnそこは、エンジニアの端くれとして、スマートにコードを書いて解決したいと決意した次第なのです。
 そこでDOMの登場です。前置きが長くなりましたが、やっと本題です。

Q. DOMってなによ?
A. Document Object Modelの略で、簡単にいえばJavaScriptからHTMLタグとかCSSのパラメータとかを書き換えられるHTML5時代のスタンダード・ウェポン。iPhoneでも使えるよ!ジオン公国のツィマッド社が開発した陸戦用モビルスーツとは親戚関係。

・座標は比率から求めよう

 画面サイズも違えば縦と横での変化もあるページを、ひとつのコードで処理する。手っ取り早くコレを実現するには、画面幅に対して画像は80%のサイズ、というように、画面の横幅に対する比率を基準にしてしまえばOKです。
残りの数値は、全て画面が描画される都度に計算しましょう。なお、タグの属性の指定には「setAttribute」を使います。

[イメージタグ]
<img src="img/map.gif" border="1" usemap="#map_test" name="map_test" id="map_img" />
*サイズの指定はしない

[JavaScript]
// mapという新しいオブジェクトにID名「map_img」(imgタグで設定したID)を割り当て
var map = document.getElementById("map_img");
// mapというオブジェクトのwidth(横幅)にwindow.innerWidth(画面の横幅)の80%(* 0.8)を指定
map.setAttribute("width",window.innerWidth * 0.8);
これで、画像の横サイズは、画面の横幅が100ピクセルの時は80ピクセルに。640ピクセルなら512ピクセルになるわけです。

で、あとはクリッカブルマップの<area>タグで、クリックエリアを指定するcoords属性の座標を地味に計算。
例えば100x100pxの画像の(x=20,y=10)の場所に座標がある場合は、(x=100*0.2,y=100*0.1)と表せます。
キモは画像のサイズを1としてゼロ座標からポイントまでの長さを小数点で表すこと。この例では、aポイントは画像の横幅に対して1:0.2の位置、縦幅に対して1:0.1の位置となるという事ですね。
var ax = document.images["map_test"].width * 0.2;
var ay = document.images["map_test"].height * 0.1;
こんな感じ。見たまんまですね。比率は、Photoshop等で頑張って測りましょう。

こうしてax,ay〜dx,dyまで4点の座標を求めたら、createAttributeでタグに直接記述されていない(予め書かないでおいた)coords属性を作成し、適用します。
var map_area = document.getElementById("AreaID");
var set_coords = document.createAttribute("coords");
set_coords.nodeValue = ax + "," + ay + "," + bx + "," + by + "," + cx + "," + cy + "," + dx + "," + dy;
map_area.setAttributeNode(set_coords);
これで座標の指定は完璧。 座標指定のスクリプトをhoge()など好きな名前の関数にして、

window.onload = function(){
	hoge();
}
とすれば、ページを読み込んだ時に実行され、無事クリッカブルマップが動くようになります。

・回転した場合の処理

iPhoneには「onorientationchange」という魔法の呪文でブラウザの回転イベントを取れるのですが、Androidでは未対応なので、ここは素直に「onresize」(画面サイズが変化した場合のイベント)を使います。


window.onresize = function(){
	hoge();
}
これでOK。 本当は「回転しないように」出来れば素晴らしいのですが、今のところ、そんな神コードは思いつかない(無くはないけど面倒)ので、まぁ今日のところは、このへんで勘弁してやろう。iPhoneめ参ったか。フヒッ。

13:49 追記
書きなぐった記事を読みながら揚げパン食ってたら思いついた。回転しない(ように見える)のは、結構簡単にできるかも?上手くできたら後日投稿します。

・まとめ

今回はクリッカブルマップでしたが、この考え方で、ブラウザの横幅が変化してもレイアウトを維持できるコンテンツが作成可能です。
使い方は色々あるので、ぜひ皆さんもDOMってみてください。

つーかiPhoneでFlash動くようになんないかなぁ!ジョブス爆発しろ!
この秋出ると噂の新型MacBookAirも、きっとまた買っちゃうんだからね!

では、また。

2010年8月11日

レディの嗜みについて
このエントリーをはてなブックマークに追加 このエントリーをlivedoorクリップに追加


はじめまして
6月にウノウ株式会社改め Zynga Japan※謎 に入社致しました mayutanです。

社内全体 MTG で flickr のプレミアムユーザであることを dis られたので
弊社のサービスでありますフォト蔵の API を使って皆さん(誰?)に許していただこうと思います。

Android 端末を見たことも触ったこともなかったので、後学のためにアプリを作ってみることにしました。
タグ的な何かを選択したらそのイメージに合った写真を一覧表示するアプリを作ってみましょう。

Aandroid アプリの開発環境はこちらを参考に整えました http://developer.android.com/sdk/installing.html

ここから直感的にアプリをデザインしてみましょう!

res ディレクトリの layout/main.xml を開いてエディター下部にあります、「レイアウト」というタブをクリックしますと・・・!

なんということでしょう!!!!!!!!!!!!!!!

なんかデザインできそうなふいんき(なぜかへんかんできない)です。

黒い画面の上で、右クリック→追加を選択すると、ダイアログが出てくるので、
無難に ListView を追加します。

「VB みたいにぐいぐいーとかそれそれーとかできるんだろうな♪」
とか思ったらできねー・・・

今回は時間がないので、仕方ないのでコードで書きます。
コードはこちらお暇な方はどうぞ→Photozoroid.java

アンドロイドはまだまだ直感的には開発できないですね。がんばれアンドロイド

さて、layout/main.xml を見てみますと、ListView を追加したことにより、新しい記述も追加されていますね。
ここにある android:id="@+id/ListView01" というのが、このリストの ID です。

実際には ListView にどうやって表示させたいオブジェクトを渡すのかといいますと、setAdapter メソッドを使います。
今回は表示するリストは固定ですので、中から指定しちゃいます///

onCreate は必ず呼ばれるメソッドで必ず実装しなければいけません。
setContentView で、引数に渡した画面が呼ばれます。
ここまでくればピン!ときますね。 main.xml に記述されているやつらです。

リストを表示させるならこれ!
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1);
adapter.add("girl");
adapter.add("food");
・・・
ListView listView = (ListView) findViewById(R.id.ListView01);
listView.setAdapter(adapter);

そして実行すると・・・!なんということでしょう・・・!

6.jpg

じゃーん。リストが出ましたね。

次はこれに onclick イベントとか実装しちゃいましょう!
それでは onClick イベントはどう実装すればいいのでしょうか。
API を見ると、どうやら AdapterView クラスが持っているこの関数を実装してやればいいらしい。

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
・・・

ここで引数にしているのは AdapterView クラスが持っているインナークラスのメソッドで、
外から呼ぶにはこうしてやります。
中見てないので適当に予想しますが、おそらく View クラスはたくさんのインターフェースを持っているのでしょう。たぶん。

次に、OnItemClickListener#onItemClick で実際にクリックされた場合の処理を実装します。

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
ListView listView = (ListView) parent;
String searchKeyWord = (String) listView.getItemAtPosition(position);
}
});

そして、これをキーワードにして API より取得したデータから画像を別画面に表示してみましょう。
遷移画面用の XML ファイルを res/layout に作成します。
そして、AndroidManifest.xml にこの View を登録。

次画面に遷移するために Intent クラスを使うようですね。そして、渡したいオブジェクトを putExtra してやります。
渡すデータは Serializable である必要があります。

次画面でデータを受け取り、API でキーワードから検索します。
コードはこちら→PhotozoViewer.java
このとき urlconn.connect で、"java.net.SocketException: Permission denied" が発生すると思います。
Manifest.xml に
uses-permission android:name="android.permission.INTERNET"
を追加して、自分の Android アプリからの通信を許可してあげましょう。。


さていよいよ画像の表示です。こちらを参考に作りました。
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/Grid2.html
ほとんどサンプルのままですが、ここでは URL から読み込んだ画像 stream を Bitmap に変換して表示してみました。


last.jpg

じゃーん!

getView はいつ呼ばれるの?と思うかもしれませんが、これは View が表示されるたびに呼ばれます。

こんな感じで簡単に Web サービスと連携させたクライアントアプリケーションが作れてしまう Android には
とても可能性を感じますね!これからも色々いじってみます。

!!!まったく関係ありませんが the clovers もよろしくお願いいたします!!!


About android

ブログ「ウノウラボ by Zynga Japan」のカテゴリ「android」に投稿されたすべてのエントリーのアーカイブのページです。過去のものから新しいものへ順番に並んでいます。

前のカテゴリはActionScriptです。

次のカテゴリはお知らせです。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Zynga Japan