🦑

RecyclerViewでデータバインディングを使うとカクつく

2022/01/10に公開約1,400字

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

ログインするとコメントできます