dimsuz
09/06/2022, 1:48 PMfun MyLayout(someState: Int) {
Layout(content) { measureables, constraints ->
if(someState) thisLogic() else thatLogic()
}
}
It updates layout whenever someState
changes, but now I want to factor out MeasurePolicy into a separate class (there will be several of them):
fun MyLayout(someState: Int) {
val policy = remember { MyMeasurePolicy({ someState }) }
Layout(content, policy)
}
class MyMeasurePolicy(private val someState: () -> Int)) : MeasurePolicy
I have made someState
into a "provider lambda" to avoid recreating policy on each someState
change (it will change more or less often).
But now my layout is not re-measured when someState
changes.
Any hints on how to do this right?ste
09/06/2022, 2:34 PMremember
ste
09/06/2022, 2:35 PMLazyList
does it)Albert Chang
09/06/2022, 2:36 PMval state = rememberUpdatedState(someState)
val policy = remember(state) { MyMeasurePolicy(state::value) }
Layout(content, policy)
dimsuz
09/06/2022, 3:05 PMmeasure
is re-invoked whenever State
values inside it change? I didn't know thisdimsuz
09/06/2022, 3:09 PMLayout(content) { m, c -> if (someState) this() else that() }
works perfectly and it "captures" someState
correctly, and the lambda itself is the same instance across someState
changes, but as soon as I try to turn it into a class (which in fact lambda is under the hood IIUC), it's suddenly not as straightforward to achieve without having a lot of allocations of said class.Albert Chang
09/06/2022, 3:43 PMMeasurePolicy
) is recreated every time someState
changes. If you do not remember
the MyMeasurePolicy
in the second snippet it will also workdimsuz
09/06/2022, 4:00 PMLayout(content) { m, c ->
Timber.d("$this, someState=$someState")
if (someState) this() else that()
}
it prints the same this
but different `someState`'s, e.g.
androidx.compose.ui.node.LayoutNode$measureScope$1@98c1123, someState=1
androidx.compose.ui.node.LayoutNode$measureScope$1@98c1123, someState=2
pointer stays the same.
Could it be because I'm running this on API 30 and it's not being compiled to an anonymous class?shikasd
09/06/2022, 8:07 PMthis
seems to be the measure scope, not lambda instance
And to answer your previous question, if state is read in measure or draw, it invalidates related layouts on writedimsuz
09/06/2022, 8:59 PMMeasureScope
, but seeing $1
made me think its a lambda's this
. But it should be the measure scope, indeed, that's the receiver.
Good to know about measure-invalidation thing, thanks! Makes sense now why it works, I didn't know this bit.