やりたいこと
旧来の AdapterView (ListView や GridView など)でいうところの OnItemSelectedListener と同じように、RecyclerView がもつアイテムにフォーカスが当たったときにその情報をコールバックする方法です。
方法
RecyclerView には OnChildAttachStateChangeListener というインタフェースが定義されています。このインタフェースのメソッドで、Adapter の生成する View が RecyclerView に attach されたタイミングが分かるので、そこで attach された View に OnFocusChangeListener をセットしてフォーカスが当たったことを検知します。
class FocusListeningRecyclerView(context: Context?, attrs: AttributeSet?, defStyle: Int) : RecyclerView(context, attrs, defStyle), RecyclerView.OnChildAttachStateChangeListener { var focusListener: OnItemFocusedListener? = null constructor(context: Context?): this(context, null) constructor(context: Context?, attrs: AttributeSet?): this(context, attrs, 0) override fun onAttachedToWindow() { super.onAttachedToWindow() addOnChildAttachStateChangeListener(this) } override fun onDetachedFromWindow() { removeOnChildAttachStateChangeListener(this) super.onDetachedFromWindow() } override fun onChildViewAttachedToWindow(view: View?) { view?.setOnFocusChangeListener { child, hasFocus -> if (!hasFocus) return@setOnFocusChangeListener focusListener?.onItemFocused(getChildAdapterPosition(child)) } } override fun onChildViewDetachedFromWindow(view: View?) {} interface OnItemFocusedListener { fun onItemFocused(position: Int) } }