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

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

Android : bindingAdapterPositionとabsoluteAdapterPositionの違い

課題

RecyclerView.ViewHoldergetAdapterPositiondeprecatedになったので、getBindingAdapterPositiongetAbsoluteAdapterPositionのどちらかに変更する必要がある。どちらを選択すればよいか。

結論

  • bindingAdapterPositionはadapterごとの位置情報を返す
  • absoluteAdapterPositionConcatAdapter全体でみたときの位置情報を返す
  • onBindViewHolderの引数のpositionbindingAdapterPositionと同じ(adapterごと)

ConcatAdapterを使っていない場合はおそらく関係なし。 取得されたpositionを使って何をしたいかによって変わってくるので適宜検討する必要がある。

調査

bindingAdapterPositionabsoluteAdapterPositionConcatAdapterで複数のAdapterを使った場合に影響する。 ドキュメントを読んでも言ってることが良く分からなかったのでコードを書いて確認。

実験

とりあえずでこさえた実験用コード。一部省略。単にコピペするとコンパイルエラーになります。

val adapter1 = object : RecyclerView.Adapter<HogeViewHolder>() {
    override fun onBindViewHolder(holder: HogeViewHolder, position: Int) {
        Log.d("Adapter1", "${holder.bindingAdapterPosition}:${holder.absoluteAdapterPosition}")
    }
    override fun getItemCount(): Int = 3
}
val adapter2 = object : RecyclerView.Adapter<HogeViewHolder>() {
    override fun onBindViewHolder(holder: HogeViewHolder, position: Int) {
        Log.d("Adapter2", "${holder.bindingAdapterPosition}:${holder.absoluteAdapterPosition}")
    }
    override fun getItemCount(): Int = 3
}
val adapter3 = object : RecyclerView.Adapter<HogeViewHolder>() {
    override fun onBindViewHolder(holder: HogeViewHolder, position: Int) {
        Log.d("Adapter3", "${holder.bindingAdapterPosition}:${holder.absoluteAdapterPosition}")
    }
    override fun getItemCount(): Int = 3
}

// ListViewにセット
listView.adapter =  ConcatAdapter(config, header,header2, adapter!!, footer)

結果

Logcatの出力結果はこちら。bindingAdapterPosition の方がadapterごとの位置情報を返していることがわかる。

// bindingAdapterPosition:absoluteAdapterPosition

D/Adapter1: 0:0
D/Adapter1: 1:1
D/Adapter1: 2:2
D/Adapter2: 0:3
D/Adapter2: 1:4
D/Adapter2: 2:5
D/adapter3: 0:6
D/adapter3: 1:7
D/adapter3: 2:8