2012年4月13日金曜日

Viewはshowしたときに描き直されるもの?(続き)

何回か前に、「Viewはshowしたときに描き直されるもの?」のタイトルで投稿した内容に関して、実験しながら少し調べてみました。その辺の話をまとめて書きます。

 

そもそもの始まりは、ウィンドウ内のレイアウトを何種類かに変更する目的で、ImageViewやLabelの表示位置を変更したときの動きでした。ViewをhideしてからUI部品の表示位置や中身を変更すると、Viewをshowしたときに、変更前の状態が一瞬表示されてしまう問題です。それを回避しようと、Viewを限りなく透明にしたり、不透明へ戻すときに時間を遅らせて対応しました。

じゃあ、View上のUI部品の位置を変えなかったら、前の状態が一瞬表示される問題は発生しないのか。そんな疑問が残ったので、調べるために実際に動くサンプルを作って実験しました。まず、複数の固定レイアウトViewを用意して、UI部品の位置を変えない方法です。これでも、UI部品の中に表示するテキストや画像は変えますから、Viewをshowしたときの内容は、前に表示した内容と異なります。試した結果ですが、やはり変更前の内容が一瞬だけ表示されました。必ず表示されるわけではなくて、表示されることもあるという感じです。どの程度の割合で発生するかは、動作している環境によって変わりそうですが、意外に多いなと思いました。

次に試したのは、Viewの代わりにWindowを使う方法です。Viewの影響が生じないようにと、UI部品はWindowに直接addしました。Windowなので、showとhideではなくopenとcloseで、表示と非表示を切り替えます。この実験でも、UI部品の内容を変更して再表示し、古い内容を一瞬でも表示されるかを確かめます。気になる結果ですが、やはり同じでした。変更前の内容が、一瞬表示される症状が発生します。これも必ずではなく、たまに発生するという感じでした。

このような結果は十分に予測できました。UI部品を表示している部分のアルゴリズムが同じであれば、UI部品をaddする対象を変えたとしても、同じような動きになって当然です。やっぱり同じだったと確認できたのですが、本当は違ってほしかったところです。もし違えば、回避策の1つとして利用できたのですけど。

 

今回は複数の方法で同じ症状が発生しましたが、解決策がないわけではありません。UI部品に前の状態を作らなければ良いのです。表示する前に毎回、古いUI部品を削除して、新しいUI部品を生成する方法です。これなら前の状態が存在しないため、一瞬でも表示される症状は起こりえません。ただし、別な注意点が生まれます。再表示する度に、古いUI部品を捨てていくため、きっちりとメモリーを解放する必要があります。この辺の注意は、慣れている人なら問題ないでしょう。

個人的にですが、本来は必要ないのに、UI部品を次々に生成する方法は嫌いです。OS、開発ツール、自分のプログラムのどこかのバグに当りそうで、メモリーリークの危険度が増します。採用する気がないので、実験での確認はしませんでした。最初に対策した方法で、問題なく動いてますからね。

0 件のコメント:

コメントを投稿