eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

続 RecyclerView in FragmentContainerView in MotionLayoutでリストが描画されない問題

Androidバージョンの切り分け

  • これはAndroid 8.x以上で発生する
  • Android 7.xでは発生しない

問題点1, そもそもRecyclerViewのWidth/Heightが0dpである

  • デフォルトのvisibilityがGONEの場合、VISIBLEに切り替えてもレイアウトのサイズが再計算されない

ワークアラウンド

  • GONEではなく、INVISIBLEを使うことでレイアウトのサイズが計算される

問題点2, adapterをsetしてもinvalidateしてもコンテンツ数がいくつあっても再描画されない

  • メインの問題
  • notifyDatasetChangedとかinsertとかdeleteとか考えつく限りのイベント通知をしたけどダメ
  • setLayoutParamsとかしなおしたけどダメ
  • invalidate()とかしたけどダメ

ワークアラウンド

  • RecyclerViewには dispatchLayout() という描画開始を行うためのpackage privateメソッドがある
  • それがコールされないらしい
    • 描画効率のため、いろんな判定が入ってるけどどこかに不具合があるんかな?
  • リフレクション使って、adapterをセットした直後とか、強制描画したいタイミングでコールしてあげると描画される
// こんなふうにするといい
fun RecyclerView.forceDispatchLayout() {
    val method = RecyclerView::class.java.getDeclaredMethod("dispatchLayout")
    method.isAccessible = true
    method.invoke(this)
}

  • Androidバージョンが8.x以上で発生するので、結構クリティカルになってきてる
  • 頑張れJetpack