LoginSignup
39

More than 5 years have passed since last update.

FragmentでKotlinのby lazyを使ってfindViewByIdするとレイアウト反映できない&リークする件

Last updated at Posted at 2017-08-23

何が起きる?

ちょっと昔のネタなのですが、時々忘れて使いそうになるので、簡単にメモしておきます。
Kotlinではviewへのアクセス時にfindViewByIdしてくれるように、こんな感じで遅延初期化して利用することができます。

private val toolbar by lazy {
    view!!.findViewById<Toolbar>(R.id.toolbar)
} 

ただlazyを使うと一度取得したものをメンバ変数として保持し、次に利用するときも同じインスタンスを返します

ここでFragmentのライフサイクルを思い出すと、以下のようにバックスタックから返ってきた時に、onCreateView()がまた呼ばれます

onCreateViewでレイアウトを新しく作って返すと、、メンバ変数で持っているViewは前に作ったレイアウトなので、リークします。また、textView.text = "hoge"などしてもレイアウトの見た目に反映されません

ではどうするべき?

ここにそれぞれの方法のメリデメがまとまっています。
https://discuss.kotlinlang.org/t/pros-cons-of-android-view-access-strategies/3160

  • 現状、lateinitが一般的っぽい?です
  • 一応、Kotlin Android Extensionでもちゃんとやってそうな雰囲気です。
  • Architecture ComponentのLifecycleOwnerとKotterKnifeを利用することができれば、以下のコードでできそうです。 https://gist.github.com/chrisbanes/fc4392dcbdc0aa5d99147dc551616676

元ネタ

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
39