多層Viewの注意点 ~redrawされない現象

 TextView が描画更新されなくなったよ。
 どうやら、onDraw イベント自体が発生してないみたい。
 invalidate() でrepaint しても効かない…。
 どないせいっちゅうねん?!

 一日中、あーでもない、こーでもないとコネくりました結果──
 どうやら原因は、View の重ね合わせにあるみたいだ…。

原因はView の多層構造

 作ってるアプリは以下のような構造になってる。

	<画面奥(下層)>

	「メッセージ表示」 (TextView)
	「選択肢表示」

	<画面手前(上層)>

 「メッセージ表示」がredraw されなくなるのは、「選択肢表示」をINVISIBLE にしてから。
 つまり「選択肢表示」がredraw されなくなってからだ。
 どうやら、上の層でredraw しないと、下の層もredraw しないらしい。
 どうりで、TextView でinvalidate() かけても描画更新されないワケだよ…。orz

 これは上の層が INVISIBLE の状態であってもredraw されない。
 また、下の層が上の層の描画範囲外の場合も、redraw されない。
 理屈はわかるけど、ひどい仕様だよ。まったく…。

まとめ

  1. 上層でredraw しないと、下層もredraw しない
  2. 上層が INVISIBLE の状態であっても同様
  3. 下層が上層の描画範囲外だとredraw されない

by the way…

 wrap_parent の多層構造となっている場合。
 最上層に透明なfill_parent のView を配置し、ソレにinvalidate をかけるようにしてやるといいかもしれない。
 今回、定期的に、最上層を描画更新するようにしたら、全体的に描画の反応がよくなった。
 てか、いままで手放しでTextViewが更新されてたのって、そういうことでもあったんだね。(^_^;

Posted in View, レイアウト. Tags: , , , . 多層Viewの注意点 ~redrawされない現象 はコメントを受け付けていません »

ゲームに適したLayout とは?

 プログラムは粘土をコネるがごとし。
 作ってるノベルアプリは、閉塞感がアチコチに見られるので、作り直しをしている最中。
 ちょうどいいので、「ゲームに適したLayout」について、復習してみよう。

※.Layout に関しては、↓コチラが詳しい
http://techbooster.jpn.org/tag/addview/

必須条件

 ”ゲーム”と一括りにしても、色々あるよね。
 だから、一般的なテレビゲーム・スタイルを前提とするよ。

 そこで必要な条件は、以下の2つだろうね。

	1. オブジェクトを重ねて表示する。
	2. 指定した位置に、オブジェクトを表示する。

 てっとり早く結論をいうと、そんなLayout はAndroid にはないんだ。

 条件・1に適合するのは、2つだけ。

	FrameLayout
	RelativeLayout

 でもこの2つとも、条件・2には適合しないんだ。
 なぜならどちらのLayout も、他オブジェクトとの相関関係やLayout の制約に縛られてしまう…。

 2つの条件を兼ね備えているのは、AbsoluteLayout だけ。
 でも、これは現在、非推奨で、eclipse で取り消し線を引かれちゃう、いらない子扱い。(w


「ボタン等のインターフェースは、Layout に従うこと。
 画像表示だけなら、View内で行え」

 おそらくAndroid はこういう理念なんだろね。
 まぁ、それはわかるし、その方が便利なこともある。
 必ずボタンは重ならず、整然と並ぶからね。
 でもさ、それじゃ困ることもあるんだよね。

 たとえばImageView をスプライトのように使う場合。
 リアルタイムにこだわらない、アドベンチャー・ゲームのようなのは、ImageView で十分。
 背景やキャラを複数のImageView で構成すれば、お手軽だし、Animation の恩恵も受けられるしね。
 AbsoluteLayout みたいなのがない現状、ゲームに適したLayout はAndroid に存在しない。
 困ったモンだ。

View を重ねて表示したい

 View を重ねて表示したい場合、FrameLayout、RelativeLayout のどちらかを使うことになる。
 それぞれの概略はこんな感じ。

●FrameLayout
 ・単純に重ねて、View を配置する。
 ・表示原点は、左上。
 ・Gravity 設定が特殊で、foregroundGravity を使う。

●RelativeLayout
 ・他Viewとの相関関係で配置する。
  宝の在り処を記すみたいでややっこしいらしい。
  「大きな木から右に三歩、そこから下って四歩、そこから左に二歩…」
  みたいな感じらしい。(^_^;
 ・配置設定をしなければ、Viewを重ねられる。
  けれど、設定をすると重ね合わせはできなくなるみたい。
 ・Gravity 設定は、他と同様のgravity を使う。

 一見すると、FrameLayout がよさげ。
 だけどpadding がなんかおかしいんだよね…。
 使ってると、なんのために存在するのか、わからなくなってくる。(^_^;

 どちらも似たりよったり、RelativeLayout を使うのが無難…
 っていうのが、今のところの印象かな。

指定した位置にView を表示したい

 最初に”できない” といったけど、実はできないことはないんだ。
 ただ色々と問題があるだけ。
 で、やってみたことと、問題をあげておくよ。

Animation を使う

 Animation を使って位置を指定する方法。

 TranslateAnimation で位置を設定して、setDuration を”0″ にする。
 そうすると、瞬間的に移動するから。
 setFillAfter とsetFillEnabled を設定して、移動後の状態を維持するようにする。

 肝心なのは、setFillAfter とsetFillEnabled の設定だけで、TranslateAnimation はフツウに移動してもいいんだけどね。

 問題は、View がボタン等のインターフェースだった場合。
 View の実体は元の位置にあるので、移動後の場所をクリックしても、実行されない。
 まぁ、インターフェースにこんな使い方をすることはないだろうけどね。(^_^;

padding を使う

 padding を使って位置を指定する方法。

 この方法だと、インターフェースの反応を維持しながら指定できる。
 ただし、ややっこしいんだよねぇ。
 Layout によっては意図した状態にならないし…。(^_^;

 ※.setPadding の引数
http://android.migimaki.com/category/view/padding

 と、まぁ、そんなこんなで、ない知恵を絞ってみたよ。
 もっと簡単でいい方法があったら、また追加していくつもり。

Posted in レイアウト, 雑記. Tags: , , , , , . ゲームに適したLayout とは? はコメントを受け付けていません »

View のレイアウト (ViewGroup)

 複数のView を重ねたい、ひとつのグループとして扱いたい。
 そんなときに使うのが、ViewGroup だね。

 ViewGroup は、View を子として内包し、親子関係を作り出せるんだ。
 代表的なところでListView なんかが、これを基礎に作られたりする。
 いってみれば、Android の土台といったところかね。
 また、ViewGroup はView の派生なので、他のViewGroup に含ませることもできるよ。

Layout シリーズ

 ViewGroup には、View を画面にレイアウトするためのclass がいくつかある。
 Layout class というものはないようなんで、オイラはそれらを勝手に、Layout シリーズと呼んでいるよ。

 具体的な使い方は他の方に任せるとして。
 ここでは特徴や違いなんかをまとめてみることにする。

LinearLayout

 子View を縦並び、あるいは横並びにレイアウトする。
 セル画やフォトショップのレイヤーみたいに、重ね合わせることはできない。
 setGravity で左端合わせ、センター合わせなんかの設定ができる。
http://developer.android.com/reference/android/widget/LinearLayout.html

TableLayout

 子View を、行や列で、格子上にレイアウトする。
 setGravity で左端合わせ、センター合わせなんかの設定ができる。
http://developer.android.com/reference/android/widget/TableLayout.html

RelativeLayout

 子View を重ね合わせてレイアウトする。
 セル画やフォトショップのレイヤーみたいな感じ。
 setGravity で左端合わせ、センター合わせなんかの設定ができる。
 レイアウト位置は座標ではなく、addRuleを使って、相関関係で設定するらしい。
 抽象的に例えて、3つのViewがあるとすると…
 View01があって。View02はその右隣。View03はその下。
 …といった具合。
 位置はそれぞれのViewの大きさが関係するので、表示イメージをなにかに下書きしないと苦労しそう。
 ※.設定しなければ、単純に重ね合わせされる。
http://developer.android.com/reference/android/widget/RelativeLayout.html

FrameLayout

 子View をひとつだけ登録できる。
 別のView を加えると置き換えらてしまう…

 って、解説を見たんだけど、やってみると、RelativeLayout のように重ね合わせされちゃうんだよね。(^_^;
 ただし他のLayout と違い、setGravity はなくて、代わりにsetForegroundGravity がある。
 setGravity のようにセンターを指定しても、そのとおりに配置されなくて、その効力未確認…。
 それに気づくまで、RelativeLayout のつもりで使ってたよ。(笑
 FrameLayout は、単純に左上合わせで重ねるだけのレイアウトなのかもしれないね。
http://developer.android.com/reference/android/widget/FrameLayout.html

 Layout に限らず、Andorid での位置指定は、なんかHTML的だね。
 どうも個人的に使い勝手がイマイチ。
 画面座標の指定があってもいいと思うのだけどね…。

レイアウトの注意

 setGravity を設定しているのに、なんか効いてないなぁと思ったら…。
 どうも、ViewGroup の中に FILL_PARENT設定がいると無効になるみたい。
 CENTER などはWRAP_CONTENT 用のものらしく、そのせいのようだ。

Posted in View, レイアウト. Tags: , , , , , . View のレイアウト (ViewGroup) はコメントを受け付けていません »