2012年01月28日 ワナビーとしての挨拶
LayerDrawableの落とし穴
LayerDrawable
こんにちはこんにちは!
みなさん、突然ですがLayerDrawable使ってますか?
( ? 皿 ?) がしゃーん
LayerDrawableだよ
自動でDrawableを重ねてくれるすごいやつだよ
LayerList - Drawable Resources | Android Developers
使ってみる
写真を添付するようなアプリをイメージして、
取り消し用の×印と添付する画像を2つほど用意して画像を切り替えてみました。
n1.png
n2.png
x.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が(少なくとも自分の)思うような動作に修正されていました。
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日 もういくつ寝ると
僕はGalaxy Nexusを手に入れることが出来たよ、あるいは独自画像でのローディング表現(Android Advent Calendar 2011 14日目)
こんばんはこんばんは!Android Advent Calendar 2011 14日目担当のytRinoです。
昨日のそばちゃんこさんのエントリを受け、「ぉяё маU〃 ゃレ£〃ぁωU〃ゃЙё?*1」状態であります。
そうそうたるメンバーが面白い記事を書いてる中、爆笑ネタも黒魔術ももってない僕は何を書こうか迷ったのですが、
以前ちらっとTLであいこんぐるぐるがーって話を見かけたときに「<rotate>ですかね?」などと軽く答えてしまったものの自分のアプリ見直したら全然別物使ってたのでそれの紹介をしたいと思います。
本当は「Androidアプリ開発に役立つ10のテクニック(キリッ」とかやりたかったんですが無理でした XD
自分で作ったローディングアイコンをぐるぐるさせたい
ここで言うローディングはIndeterminateなローディングです。つまり進行度の表現がないやつです。
標準で使えるぐるぐるもいいけどせっかくなので自分で作った画像を回してみます。
用意するもの:
画像
この画像は /res/drawable/ic_dialog_onmyou.png などと適当な名前をつけて放り込んでおきます。
アニメーションさせるためのリソース
回転させるためのアニメーションに<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();
しかしandroid:durationが反映されてない気がするのは気のせいでしょうか。
ちなみにSDKに入ってたXMLにはandroid:framesCountという属性もあったり、Eclipseでもandroid:framesDurationとともに候補が出たりするのですがうまくいかなかったので削ってます。謎が多い。
他に書く予定候補だったもの
ListViewの各itemに横幅フィットさせて縦横比維持の縦クロップな画像を設定する
SQL初心者が初心者に送るAndroidなSQL
AsyncTaskとネットワーク通信
BroadcastIntentキャッチした話
AIDLとサービスで玄人気分
無理でしたXD
おまけ
ドゥーコモゥ ギャアクシィネェクスゥス
そばちゃんこさんすいません、でも僕には稟議を通す相手がまず欲しいです。
というわけで12月2日、Galaxy Nexusを買いました。HT-03Aからの機種変で。
HT-03Aからの機種変で。1台持ち標準ROMで使っていたHT-03Aからの機種変で。
ドヤァ…
まあ正しくはメガネケースことIS01があるんですが、もうよくここまで使ってこれたなと誇りにすら思います。
もうぎゃらねくさんからは戻れない…
と言いたいところですがHT-03AがGalaxy Nexusに勝るいいところがあります。
特にトラックボール、なぜこれほどまでに見かけないのでしょうか。文字入力の編集やアプリ/ブラウザの操作にも大活躍なのに…
苦労してリストやら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ヶ月周期
Google Developer Day2011
11/1 Google Developer Day 2011 Japan @パシフィコ横浜
GDD11jp参加者の皆さん、スタッフの皆さんお疲れ様でした。
自分は当初DevQuizもやってないし優先枠とかも考えてなかったのでもとより参加しないつもりだったのですか、ボランティアでちゃっかり参加してしまいました。
当日はほとんどラウンジでOpencall担当としてのんびりしてました。kabayanさん持参の風船をそのへんの人につけたりChrome PCいじったり。
参加して何が良かったか
って言えばいろんな人と会えたこと。これにつきます。…まあ自由時間もあったのにセッション全然見てないから、セッションの内容で語れないってのもあるんですが。
自分がこんなことを言えるのも、「ガチで会いに行く」のではなくて「ちょうどいたのでちょっと話してみた」ぐらいの緩さだからこそだと思います。人見知りするのでそれぐらいの緩さじゃないと死んじゃうXD。 就活で「人脈出来ました(キリッ)」とかそういうことをするために行ってるんじゃないのでね。*1
というわけで今後もゆるーく色々イベントや勉強会など参加したいです。
終わった後は
スタッフ打ち上げ。しかしもともとsekitobaさん*2の計らいにより(?)非公式懇親会だけは参加するつもりだったので、ちょっと飲んでから勢いでadamrocker*3さんに突撃したあとダッシュで非公式の方へ移動しましたとさ。たぶんいろんな人に会えて感動っていうのはこの非公式懇親会が一番やばかったような気がします。うん、やばい。TLでしか知らない人が目の前にたくさん。こわいぇ
あと、自分のアプリ知ってますよ、って言われるとやっぱり嬉しい。
というわけで
みなさん、今後とも宜しくお願いします。
# はてブロに試し書きした記事をちょこっと修正してこっちにも投下しておきます。


