Hatena::ブログ(Diary)

ちりもつ

2012年01月28日 ワナビーとしての挨拶

ytRino2012-01-28

LayerDrawableの落とし穴

LayerDrawable

こんにちはこんにちは!
みなさん、突然ですがLayerDrawable使ってますか?

   △  ¥ ▲
  ( ? 皿 ?)  がしゃーん
LayerDrawableだよ
自動でDrawableを重ねてくれるすごいやつだよ

LayerList - Drawable Resources | Android Developers

使ってみる

写真を添付するようなアプリをイメージして、
取り消し用の×印と添付する画像を2つほど用意して画像を切り替えてみました。

f:id:ytRino:20120128183613p:imagen1.png

f:id:ytRino:20120128183612p:imagen2.png

f:id:ytRino:20120128183611p:imagex.png

test_layer.xml 上に書いたものから置かれるので下にあるものが上に来ます。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/number">
        <bitmap
            android:src="@drawable/n1"
            android:gravity="center" />
    </item>
    <item>
        <bitmap
            android:src="@drawable/x"
            android:gravity="bottom|right" />
    </item>
</layer-list>

これをImageViewに設定するだけ。

    <ImageView
        android:id="@+id/image"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"

        android:src="@drawable/test_layer"
        />

楽ちんですね。

LayerDrawable#setDrawableByLayerIdで先ほどの<item>のIDと新しくセットするDrawableを指定して入れ替えます。


       LayerDrawable mLayer = (LayerDrawable)((ImageView)findViewById(R.id.image)).getDrawable();
       ...
       // 画像URIから適当にDrawable生成したりして
        Drawable drawable = getNewDrawable();
       // 入れ替え
        mLayer.setDrawableByLayerId(R.id.number, drawable);
       // 再描画
        mLayer.invalidateSelf();

単純に添付取り消しを表現するなら mLayer.setVisible(View.INVISIBLE)でいい気がする。

問題発生

こんな感じで順調に行くかとおもいきや、問題が。
Galaxy Nexusだとちゃんと切り替わるのに、他のいくつかの端末では切り替えて再描画の要求をだすと消えます。×印を残して。

結論から言うとICSでDrawbleがちょいちょい変わっていて、#setDrawableByLayerIdが(少なくとも自分の)思うような動作に修正されていました。

2.3の該当箇所
http://tools.oesf.biz/android-2.3_r1.0/xref/frameworks/base/graphics/java/android/graphics/drawable/LayerDrawable.java

    266     public boolean setDrawableByLayerId(int id, Drawable drawable) {
    267         final ChildDrawable[] layers = mLayerState.mChildren;
    268 
    269         for (int i = mLayerState.mNum - 1; i >= 0; i--) {
    270             if (layers[i].mId == id) {
    271                 layers[i].mDrawable = drawable;
    272                 return true;
    273             }
    274         }
    275 
    276         return false;
    277     }

シンプルですね。つづいでICS
http://tools.oesf.biz/android-4.0.1_r1.0/xref/frameworks/base/graphics/java/android/graphics/drawable/LayerDrawable.java

    278     public boolean setDrawableByLayerId(int id, Drawable drawable) {
    279         final ChildDrawable[] layers = mLayerState.mChildren;
    280 
    281         for (int i = mLayerState.mNum - 1; i >= 0; i--) {
    282             if (layers[i].mId == id) {
    283                 if (layers[i].mDrawable != null) {
    284                     if (drawable != null) {
    285                         Rect bounds = layers[i].mDrawable.getBounds();
    286                         drawable.setBounds(bounds);
    287                     }
    288                     layers[i].mDrawable.setCallback(null);
    289                 }
    290                 if (drawable != null) {
    291                     drawable.setCallback(this);
    292                 }
    293                 layers[i].mDrawable = drawable;
    294                 return true;
    295             }
    296         }
    297 
    298         return false;
    299     }

2倍ぐらいに増えてる… 285,286、怪しさ満点です。さっきのコードのsetDrawableByLayerIdの前に付け加えてみます。

       // 画像URIから適当にDrawable生成したりして
        Drawable drawable = getNewDrawable();
       // 入れ替える前rのDrawableからbounds取ってきてセット
        Rect bounds = mLayer.findDrawableByLayerId(R.id.number).getBounds();
        drawable.setBounds(bounds);
       // 入れ替え
        mLayer.setDrawableByLayerId(R.id.number, drawable);
       // 再描画
        mLayer.invalidateSelf();

無事

動きました。

コード貼る所が無いので出来上がったAPKを置いておきます。
とりあえず見てみるかという方はどうぞ。apk
上のDrawableがそのままの処理で、下のDrawableがRectを設定するようにしたものです。GNだとどっちも同じように動き、2.3以前だと上は最初にボタンを押したときに消えてそのまま。IS01で動かしたらImageViewの大きさがばらばらになりました。

2011年12月14日 もういくつ寝ると

14日目です><

僕はGalaxy Nexusを手に入れることが出来たよ、あるいは独自画像でのローディング表現(Android Advent Calendar 2011 14日目)

こんばんはこんばんは!Android Advent Calendar 2011 14日目担当のytRinoです。

昨日のそばちゃんこさんのエントリを受け、「ぉяё маU〃 ゃレ£〃ぁωU〃ゃЙё?*1」状態であります。

そうそうたるメンバーが面白い記事を書いてる中、爆笑ネタも黒魔術ももってない僕は何を書こうか迷ったのですが、
以前ちらっとTLであいこんぐるぐるがーって話を見かけたときに「<rotate>ですかね?」などと軽く答えてしまったもの自分アプリ見直したら全然別物使ってたのでそれの紹介をしたいと思います。

本当は「Androidアプリ開発に役立つ10のテクニック(キリッ」とかやりたかったんですが無理でした XD

自分で作ったローディングアイコンをぐるぐるさせたい

ここで言うローディングはIndeterminateなローディングです。つまり進行度の表現がないやつです。

標準で使えるぐるぐるもいいけどせっかくなので自分で作った画像を回してみます。

用意するもの:

  • 回りそうな画像(透過png)
  • 設定XML
画像

今回は自分アプリでも使ってる陰陽玉をつかいます。

f:id:ytRino:20111213211921p:imageよく回りそうですね。

この画像は /res/drawable/ic_dialog_onmyou.png などと適当名前をつけて放り込んでおきます。

アニメーションさせるためのリソース

簡単なアニメーションXMLで設定できます。

回転させるためのアニメーションに<rotate>というのがあるようですがここではそれは置いといて別の方法を使ってみます。

animated-rotate

animated-rotateです。アニメーションではなくみんな大好きDrawableです。

android:pivot[X|Y]で画像の回転軸を設定します。%指定が使えるので中心指定も楽ちんです。

android:drawableで回転させるDrawable(画像)を指定します。

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_dialog_onmyou"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="100"
 />

こいつ自体もDrawableなので/res/drawable/load_spin.xml などと保存しておきます。

あとはProgressBarやProgressDialogでsetIndeterminateDrawable()にこのDrawableを突っ込んであげましょう。

	private ProgressDialog dialog;
	dialog = new ProgressDialog(MyActivity.this);
	dialog.setIndeterminateDrawable(getResources().getDrawable(R.drawable.load_spin)); // さっきのDrawableを指定
	dialog.setCancelable(false);  //ただ試す場合は付けないように
	dialog.setMessage(getResources().getText(R.string.nowloading));
	dialog.show();

f:id:ytRino:20111213234801p:image:h360よく回ってます。確実に。

しかしandroid:durationが反映されてない気がするのは気のせいでしょうか。

ちなみにSDKに入ってたXMLにはandroid:framesCountという属性もあったり、Eclipseでもandroid:framesDurationとともに候補が出たりするのですがうまくいかなかったので削ってます。謎が多い。

他に書く予定候補だったもの

Android初級者が送るシリーズ

ListViewの各itemに横幅フィットさせて縦横比維持の縦クロップな画像を設定する
SQL初心者初心者に送るAndroidSQL
AsyncTaskとネットワーク通信
BroadcastIntentキャッチした話
AIDLとサービスで玄人気分

無理でしたXD

おまけ

ドゥーコモゥ ギャアクシィネェクスゥス

そばちゃんこさんすいません、でも僕には稟議を通す相手がまず欲しいです。
というわけで12月2日Galaxy Nexusを買いました。HT-03Aからの機種変で。
HT-03Aからの機種変で。1台持ち標準ROMで使っていたHT-03Aからの機種変で。

ドヤァ…
まあ正しくはメガネケースことIS01があるんですが、もうよくここまで使ってこれたなと誇りにすら思います。
もうぎゃらねくさんからは戻れない…


と言いたいところですがHT-03AGalaxy Nexusに勝るいいところがあります。

  • 程よい大きさ(最近の機種はどれもでかすぎ ray欲しい)
  • トラックボール(全く見かけないんだがどういうことですか)

特にトラックボール、なぜこれほどまでに見かけないのでしょうか。文字入力編集アプリ/ブラウザ操作にも大活躍なのに…
苦労してリストやらselectorでfocusedの対応に悩んだこともあったのに…
何が言いたいかというと、トラックボール付き機種出してくださいお願いします!

Google「これからはソフトキー前提だわカーッ」
\(^o^)/

最後

今年ついにAndroidでもAdventCalenderが行われました。
どうもほかの技術系Adventとは空気が違うような気がしないでもないですがそれもAndroidっぽいってことで一つ。
発起人のようてんさん@youten_redo に感謝!


そして今日(昨日?)の大ニュースといえば Andorid向け日本語入力のSimejiをバイドゥが買収 ですね。
あだむさん@adamrocker、矢野さん@yanorinおめでとうございます!
HT-03Aカバーの裏にはSimejiシールが貼ってあるしぎゃらねくさんになった今でもSimejiで入力してます。
HT-03Aでは「おい、いまキーボード呼んでない!」ということもありましたがやっぱりSimeji Love
今までもこれからもありがとうございます

GDD打ち上げで「パスポート取ったほうがいいよ」とあだむさんに言われたから11/1はパスポート取ったほうがいいよ記念日


最後自己紹介
エントリをご覧いただきまして、ありがとうございます
@ytRinoっていいます。「Uたろう」って呼んでください。 うそです、「いいの」の方が落ち着きます。
大学生です。来年の春に卒業します。うそです、まだできません。
Android好きです。Java好きです。プログラミング大好きです。
デ部と町田支部と酒部には行ってるかもしれないので、僕を見かけたら声でも石でも投げてください。
どうも、ありがとうございました〜(*´▽`*)*2

Android Advent Calendar 2011、
今日の裏エントリは黒えあさん@kuroair 黒えあ-らぼ-: Androidとセキュリティ です!
明日の表エントリは、すますさん@ryosms です!

#もはや何が表で何が裏なのかさっぱりわからない

2011年11月17日 3ヶ月周期

#GDD11jp

Google Developer Day2011

11/1 Google Developer Day 2011 Japan @パシフィコ横浜

GDD11jp参加者の皆さん、スタッフの皆さんお疲れ様でした。

自分は当初DevQuizもやってないし優先枠とかも考えてなかったのでもとより参加しないつもりだったのですか、ボランティアでちゃっかり参加してしまいました。

当日はほとんどラウンジでOpencall担当としてのんびりしてました。kabayanさん持参の風船をそのへんの人につけたりChrome PCいじったり。

参加して何が良かったか

って言えばいろんな人と会えたこと。これにつきます。…まあ自由時間もあったのにセッション全然見てないから、セッションの内容で語れないってのもあるんですが。

自分がこんなことを言えるのも、「ガチで会いに行く」のではなくて「ちょうどいたのでちょっと話してみた」ぐらいの緩さだからこそだと思います。人見知りするのでそれぐらいの緩さじゃないと死んじゃうXD就活で「人脈出来ました(キリッ)」とかそういうことをするために行ってるんじゃないのでね。*1

というわけで今後もゆるーく色々イベント勉強会など参加したいです。

終わった後は

スタッフ打ち上げ。しかしもともとsekitobaさん*2の計らいにより(?)非公式懇親会だけは参加するつもりだったので、ちょっと飲んでから勢いでadamrocker*3さんに突撃したあとダッシュで非公式の方へ移動しましたとさ。たぶんいろんな人に会えて感動っていうのはこの非公式懇親会が一番やばかったような気がします。うん、やばい。TLでしか知らない人が目の前にたくさん。こわいぇ

あと、自分アプリ知ってますよ、って言われるとやっぱり嬉しい。

というわけで

みなさん、今後とも宜しくお願いします。

# はてブロに試し書きした記事をちょこっと修正してこっちにも投下しておきます。

*1:それはわかるんだけど…という違和感についてはいずれ。

*2http://netyougo.com/slang/2770.html

*3:言わずもがなSimejiの開発者です