Reputation: 442
A few days ago, I posted this question about using synthetic properties when you include the same layout in a screen multiple times.
The answer was awesome but after I tried it more for a few days, I noticed a strange behaviour:
When going forward from the fragment (the one containing the references to the view obtained by the lazy delegate) and then coming back ( I use transaction.commit()
and manager.popBackStack()
, to do this ), the labels will be empty. I already checked with the debugger if anything is null there, and nothing is.
The only solution that seems to work is replacing the by lazy
with lateinit var
and assigning them in onViewCreated
.
Do you know why? Is the solution I used still "good" as a kotlin idiom?
I include the two pieces of code for the sake of completeness:
Partially working one:
private val foundTitle by lazy { detailContainer1.title }
private val foundDescription by lazy { detailContainer1.description }
private val wantedTitle by lazy { detailContainer2.title }
private val wantedDescription by lazy { detailContainer2.description }
Always working one:
private lateinit var foundTitle: TextView
private lateinit var foundDescription: TextView
private lateinit var wantedTitle: TextView
private lateinit var wantedDescription: TextView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
foundTitle = detailContainer1.title
foundDescription = detailContainer1.description
wantedTitle = detailContainer2.title
wantedDescription = detailContainer2.description
}
Thanks in advance
Upvotes: 5
Views: 2119
Reputation: 17268
Fragment's have their view destroyed when they get removed - but lazy
fields do not clear their reference so they are essentially leaking previous view.
If possible You should always have unique view IDs within your project, even if they are not within same layout - having duplicates can cause multiple problems (like yours).
If you were able to use kotlin extensions directly, it would generate code for finding, caching and clearing the view cache when fragments view is destroyed automatically.
Try to "get" views from fragments cache instead of assigning them to fields:
private val foundTitle
get() = detailContainer1.title
private val foundDescription
get() = detailContainer1.description
private val wantedTitle
get() = detailContainer2.title
private val wantedDescription
get() = detailContainer2.description
Upvotes: 7