【Android】RecyclerView で DataBinding を使うときは executePendingBindings が必要
RecyclerView
でデータバインディングを使っていたのですが、「リストアイテムのレイアウトサイズが異なる画面でスクロール」すると「カクツクような違和感」があったので、改善策を探していたところ、executePendingBindings
というメソッドの存在を知りました。
この記事では、「RecyclerView + DataBinding + リストアイテムのレイアウトのサイズが異なる
」ときに発生する「カクツクような違和感の解消法」をご紹介したいと思います。
結論: バインディングした後に「executePendingBindings」を呼び出す
タイトルのとおり、バインディングした後にexecutePendingBindings
を呼び出しますが、まずはexecutePendingBindings
について。
executePendingBindingsとは?
executePendingBindings
は「即時バインディング」といいます。
通常のバインディングでは、レイアウトに定義した変数(variable
)を変更すると、次のフレームの前に変更されるようスケジュールが設定されるので、すぐに内容が反映されません。
なので、スクロールしてレイアウトが表示されたときに遅れて、「バインディングの反映 -> バインディングされた変数(オブジェクト)の内容で、Viewのサイズが変わる」ということが起きて、カクついて見えているんだと思います。
そこで、バインディングした後にexecutePendingBindings
を呼び出すことで、変更内容をすぐに反映させることが出来ます。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="user"
type="com.example.executependingbindingssample.User" />
</data>
// 例: User.ktというオブジェクトをセット
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val user = getItem(position)
holder.binding.user = user
// バインディングした後に呼び出す
holder.binding.executePendingBindings()
}
まとめ
リストアイテムのレイアウトのサイズが同じ場合はどうなんだろう?と思い、実際に試してみましたが、特に違和感は感じませんでした。
なので、レイアウトのサイズが同じ場合、executePendingBindings
は必要ないのかな?と感じましたが、実際どうなんだろうか...(レイアウトの内容によりそうだけど)。
Discussion