setLayoutParamsには親のViewGroupに属するLayoutParamsをセットする

基本的に私はViewをJavaのコードで生成することは稀なので、適当にやっていたのだけれど。

RelativeLayout parent = new RelativeLayout(context);
TextView hope = new TextView(context);
parent.addView(hoge);

みたいな感じでコードから生成したとき、このViewのwidth/heightにmatch_parentとかwrap_contentを設定するのに、LayoutParamsを使うことになると思う。

parent.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.MATCH_PARENT, RelativeLayout.WRAP_CONTENT));
hoge.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.MATCH_PARENT, RelativeLayout.WRAP_CONTENT));

みたいに。そこでLayoutParamsを指定するのに、なぜいちいちRelativeLayoutとかクラスを指定しているのだろうと、毎度のこと不思議に思っていた。別にViewGroupでもいいんじゃないのかとか思いながら、基本的にはAndroid Studioの補完によって出てきたものをそのまま使っていた。

とりあえずViewGroup指定しとけばオッケーだと思っていたのだが、どうもそれはオッケーではなかったらしい。たまたま今まで問題に出くわしていなかっただけだった。

親のViewGroupのLayoutParamsを使わなければならない

まあ大抵の場合、ViewGroupを使っておけば問題ないのだろう。LinearLayoutとかRelativeLayoutとかFrameLayoutとかにコードから生成したViewを追加していくだろうから。しかしバージョンによってはそれではうまく動かないことがあるらしいということがわかった。

私が出くわしたのは、ListViewに表示するViewをコードから生成したときに、ViewGroup.LayoutParamsを使うとクラッシュするという症状だった。ちなみにAndroid7で確認したら問題なく動いていたので、普通にスルーしていた。4.4で確認したらクラッシュした。

ListViewもViewGroupを継承しているのだからViewGroupでも問題ない気がするのに・・・。

ちなみにこれはAbsListView.LayoutParamsを使うことで、4.4でも7でもクラッシュしなくなくなった。

この問題から学んだことは、LayoutParamsは親のViewGroupに属するLayoutParamsを使わないといけないのだということである。LayoutParamsいっぱいあって適当に選んでいたが、今後はちゃんと指針が持てたという意味で、よい経験ができた。

Amazonのほしいものリストを公開しています。仕事で欲しいもの、単なる趣味としてほしいもの、リフレッシュのために欲しいものなどを登録しています。 寄贈いただけると泣いて喜びます。大したお礼はできませんが、よりよい情報発信へのモチベーションに繋がりますので、ご検討いただければ幸いです。