ImageView
リンク
不必要に複雑なクラス
このクラスはとにかく不必要に複雑すぎる。 やりたいことは単にDrawable等をセットして描画したいだけであるのに、異様に複雑で訳がわからない。 これは設計として間違いである。あらゆる要求を満たすクラスを用意するのは構わないのだが、多くのユーザが普通に使える機能を持つクラスでそれをラップすべきであろう。
ImageViewのサイズの決め方
リンク先で説明されているように、ここは非常に複雑になっている。普通の人は以下のようにすべきである。
- wrap_contentは絶対に使わない。これを使うと話がかなりややこしくなる。
- fill_parentか、あるいはサイズを明示的に指定する。
描画のしかた
以下ではImageViewの中にDrawableその他がどのように表示されるかについてだけ見ていく。 この描画のしかたの制御はImageView#setScaleType(ScaleType type)メソッドで行うらしい。
まず、必ずしもImageViewのサイズとそこに描画されるイメージのサイズが一致するとは限らない。そもそもイメージの「サイズ」とは何なのかが問題であるが、ビットマップの場合には当然のことながらピクセルサイズであり、これをそのまま1対1でデバイスのピクセルに描画すれば解像度によって大きさが異なってしまうため、ほとんど常に伸縮されて描画されることになる。
この伸縮のタイプには二種類あり、
- アスペクト比を保持せずに伸縮
- アスペクト比を保持して伸縮
例えば、ImageViewの領域が横長の大きさのときに、縦長のイメージを描画する場合、アスペクト比を無視してもよいのか、保持したいのかをまず決める必要がある。
アスペクト比を保持せずに伸縮する場合
ScaleTypeとして、FIT_XYを使用する。 イメージはImageViewの横一杯、縦一杯に広がって描画されるらしい。 ただし、paddingとして指定した領域には描画されない。
アスペクト比を保持して伸縮する場合
FIT_CENTER, FIT_END, FIT_STARTは、ImageView一杯(padding部を除く)に描画する。 もちろん、イメージのアスペクト比は保持されるので、ImageView内に「余った部分」が現れる。 つまり、描画イメージをImageView内のどこに置くかについて選択肢がある。
- FIT_CENTERはできるだけ中央におく。例えば、余る部分が縦方向であれば、上下の余り部分が等しくなるようにする。
- FIT_STARTはできるだけ左上におく。例えば、余る部分が縦方向であれば、下側だけに現れるようにする。
- FIT_ENDはできるだけ右下におく。余る部分が縦方向であれば、上側だけに現れるようにする。
CENTER_INSIDE, CENTER_CROPは使いものにならない。
- CENTER_INSIDEは、説明を読むといっけんFIT_CENTERと同じ処理のような気がするのだが、実際にはCENTER(後述)と同じ機能しかないようだ。。。。バグのような気がする。
- CENTER_CROPは、伸縮したイメージがpaddingを除く描画領域を含むようにする。この場合、イメージのすべてを描画することはできず、上下あるいは左右がカットされる。
※実際には描画時にpaddingが無視されてしまう。例えば、ImageViewが正方形であるとして、そこに上下左右のpaddingを設定し、横長のイメージを描画する場合、上下方向のpadding部分には描画されないが、左右方向は平気で描画されてしまう。
その他の描画方法
CENTERは単純にイメージのサイズで描画して、それを描画領域の中央におく。とはいっても、スクリーン上のイメージのサイズとは何であるのか定義はない。
MATRIXはsetImageMatrix(Matrix matrix)メソッドで指定したMatrixにより任意のアフィン変換を行って描画することになる。 つまり、イメージは拡大縮小はもちろんだが、回転や押し潰しなどの効果を使って描画されることになる。 Matrixを参照のこと。
使い方のまとめ
サイズの決め方については最初に記述した通り、描画の仕方については以下のとおり。
- CENTERはイメージサイズ(って何?)で描画するので使いものにならない。
- CENTER_INSIDEはバグっている。CENTERと同じ機能しかない。
- CENTER_CROPは機能的に使い物にならない。こんなものが必要な人はいないでしょう。
- MATRIXは上級者向け。普通の人は必要ない。
FIT_START, FIT_ENDを使うより、ImageView自体のgravityを設定した方がよいでしょう。
- FIT_XYは普通の人には必要ない。
ということで、普通の人にはFIT_CENTERしか必要はないと思われる。 また、マニュアルにも何の記述も見られないが、ソースを調べてみるとscaleTypeのデフォルトはFIT_CENTERである。