前人未踏の領域へ Androidアプリ開発編

Androidアプリ開発に関する調査メモ置き場。古い記事にはアプリ以外も含まれます。

RecyclerView内のアイテムが表示されたタイミングを取得する

課題

RecyclerView内のあるViewTypeのアイテムが表示されたタイミングでImpressionイベントを計測したい。

対応

RecyclerView.Adapter.onViewAttachedToWindow() メソッドをオーバーライドする。

    override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
        super.onViewAttachedToWindow(holder)

        if (holder.itemViewType == TYPE_HOGE) {
            if (BuildConfig.DEBUG) {
                Log.d(TAG, "onViewAttachedToWindow called")
            }
            sendGoogleAnalyticsEvent()
        }
    }

注意点

AdapterのnotifyDataSetChanged()が呼ばれると画面表示中でもに見えても実際には再描画が発生してonViewAttachedToWindowが呼ばれてしまう。 notifyItemChangedを使い、かつRecyclerViewのitemAnimatorをnullにしておく必要がありそう。

感想

これまでは ViewTreeObserver.onPreDrawListener を使っていたけれど、ちゃんとremoveしてあげないと メモリーリークの心配があったりonBindViewが一度しか呼ばれないようなケース(再利用が発生しない) ではそもそもonPreDrawListenerがセットできないなど問題があったが、これでまるっと解決した気がする。