eaglesakuraの技術ブログ

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

特定条件下でMotionLayout配下のViewが再描画されない問題のWorkaround

バージョン

"implementation"("androidx.constraintlayout:constraintlayout:2.0.0-beta2")

問題点

  • MotionLayout配下にFrameLayoutを配置し、動的にコンテンツを入れ替える
  • MotionLayoutはアニメーションで2つのレイアウト間を遷移させている
  • 特定条件下で、MotionLayoutの初期状態を 遷移後のレイアウト にしている
  • 処理としてはこんなの
if (/* 特殊な場合 */) {
    // 強制的に遷移状態にしておく
    motionLayout.progress = 1.0f
    motionLayout.transitionToEnd()
}
  • そしてActivityの再生成を行う
    • DeveloperオプションでActivity強制破棄 -> Recentして再度アプリに戻るとすぐに再現できる
  • コレをやると、MotionLayout自体はEnd位置になっていて想定通りだが、MotionLayoutの中にあるchildFragmentの中のコンテンツが正常に描画されない

ワークアラウンド

  • 強制的に再レイアウトと再描画を繰り返す
  • ずっとやるとマシンパワーを喰うので、1秒程度やれば再描画されてOK
launch(Dispatchers.Main) {
    val invalidateTimeout = (System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(1))
    while (System.currentTimeMillis() < invalidateTimeout) {
        motionLayout.requestLayout()
        motionLayout.invalidate()
        delay(1000 / 60)
    }
}

何が問題だったのか?

  • よくわからないが、しばらく様子を見よう
  • betaだし