57
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

元ネタ

57
39
0

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
  3. You can use dark theme
What you can do with signing up
57
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?