質問: inflater.inflate(R.layout.photo_item_layout, container, false); PhotoItemView photoItemView=new PhotoItemView(view); view.setTag(photoItemView); ``` `PhotoItemView`は`ViewHolder`的な役割などを持たすために作成したクラスです。 現状一部`View`の見た目変更もさせているので、ただの`ViewHolder`ではないです。 (現在試行錯誤中なので、設計が良いかどうかはとりあえず気にしない方向でお願いします。) ここで生成される`view`は`LinerLayout`を親クラスとする`PhotoItemViewGroup`というクラスの`View`なのですが、そこまでダウンキャストする必要もないのでしていません。 そもそもなぜ`PhotoItemViewGroup`を作成しているかというと、 `inflate`したら`ListView`の1アイテムがまとまっているので、 それを新たなクラスにしまわずにそれ自体を操作すれば良いのでは?と思ったからです。 1アイテムは`ImageView`・`TextView`・`Button`の3つで構成されています。 `PhotoItemView`ではコンストラクタで`findViewById`から各種`View`の取得と記憶をやらせていて、あとで`Adapter`で各種`View`を取得する時も問題はありません。 `PhotoItemViewGroup`ではコンストラクタで取得等をやらせると`null`になっていますが、`Adapter`で`PhotoItemView`から取得する処理の前後に`findViewById`するとうまくいきます。 `Adapter`で`PhotoItemView`から各種`View`を取り出す処理は`PhotoItemViewGroup`で`onLayout`が呼ばれるよりも前に行われていたのですが、`onLayout`は`View`が生成される時に呼び出されるわけではなくレイアウトの変更の時のみでしょうか? また、実際に`View`が生成される(た)タイミングで呼び出されるメソッドがあれば教えてください。
回答: カスタムビューのコンストラクタはカスタムビューが生成された時点で呼ばれるため、 子ビューは空っぽの状態であり`findViewById`等のメソッドで取得することはできません。 代わりに`View#onFinishInflate()`でカスタムビューのInflateが完了した時点のイベントを受け取ることができるのでこちらで処理をしてはいかがでしょうか。 また、`View#onLayout()`は子ビューの配置をし直すべき時(ビューのサイズ・位置が変更された時など)に呼ばれます。ビューが生成された時のみ呼ばれるわけではありません。 その他のイベントについても公式リファレンスに書かれていますので一読されるとよいかと思います。(「`Implementing a Custom View`」セクションにまとまっています)