https://kotlinlang.org logo
#compose
Title
# compose
k

Kshitij Patil

01/30/2021, 4:40 PM
Thanks a lot for alpha11 release. It solved all my keyboard related issues 🥳🥳 Can’t wait to see what’s cooking up next. Just tried out this snippet to pre-focus a TextField on First load and it worked like charm. Let me know if anything is wrong doing it this way
Copy code
val fieldFocus = remember { FocusRequester() }
LaunchedEffect(key1 = Unit) {
    addressFocus.requestFocus()
}
K 1
z

Zach Klippenstein (he/him) [MOD]

01/30/2021, 5:25 PM
If you don’t need a coroutine (and I don’t think
requestFocus
is suspending), I would use
SideEffect
instead of
LaunchedEffect
.
g

grandstaish

01/30/2021, 7:34 PM
Zach do you mean
DisposableEffect
? I think
SideEffect
runs after every recomposition. (Asking bc I’m using
DisposableEffect
to replace my
onCommit
calls, but having an empty
onDispose
lambda feels weird to me, so want to check I’m not missing an obvious API)
i

Ian Lake

01/30/2021, 7:49 PM
onCommit
->
SideEffect
. It is supposed to feel wrong using
DisposableEffect
if you have nothing to dispose
👀 1
z

Zach Klippenstein (he/him) [MOD]

01/30/2021, 7:53 PM
My bad, i remembered incorrectly (thought
SideEffect
replaced
onActive
, not
onCommit
).
👍 1
g

grandstaish

01/30/2021, 7:53 PM
onCommit
took a subject though right? Which
SideEffect
doesn’t as far as I can see
so it seems like I’m forced to use:
Copy code
DisposableEffect(Unit) {
  // do thing
  onDispose { } 
}
i

Ian Lake

01/30/2021, 8:14 PM
DisposableEffect(Unit)
is the equivalent to
onActive
, looking at the commit that made the changes: https://android-review.googlesource.com/c/platform/frameworks/support/+/1548515
👍 3
a

Andrew Neal

01/30/2021, 8:20 PM
It may feel wrong to have an empty
onDispose
, but I think that is the correct way to handle things right now. There isn't another effect api to use in place of it at the moment. If you want to save yourself some typing, you could make your own
DisposableEffect
with an empty
onDispose
and just import that one when you need it. Here are some examples with empty
onDispose
calls: Modifier.focusable Swipeable.rememberSwipeableStateFor Modifier.swipeable NavHost DemoFilter.FilterField
🙌 1
🕵️‍♂️ 2
g

grandstaish

01/30/2021, 8:25 PM
thanks all, good to know
i

Ian Lake

01/30/2021, 8:40 PM
Yup, having no cleanup isn't a problem, just note as per the deprecation messages on onCommit, etc that using
DisposableEffect
without any parameters is "usually incorrect" to use @Adam Powell's words
👀 1
a

Adam Powell

01/30/2021, 8:42 PM
Yeah, as is using it with an empty
onDispose
clause
Empty onDispose with keys often means you're trying to use composition as an event dispatch mechanism, which is a road that spirals into hacks to fix the hacks 🙂
Or that you're trying to get composition to enforce idempotence in your state object APIs that would be better implemented in those objects themselves
If you can better hoist that focus requester and call it at a more domain-appropriate event point you'll probably have a better time
m

Mantas Varnagiris

01/31/2021, 12:48 PM
So if I want to request a focus on the text field when the screen is first shown - what would be the recommended approach for that?
👀 2
k

Kshitij Patil

01/31/2021, 12:49 PM
I want to have TextField pre-focused, that's the only logic here. Where could I hoist the focus requester in this case? I picked
LaunchedEffect
because it's called once at the start and on subject changed afterwards, which in my case is
Unit
👀 1
👍 1
💯 1
a

allan.conda

02/02/2021, 6:38 AM
@Kshitij Patil what kind of issues did you have that were fixed?
k

Kshitij Patil

02/02/2021, 9:17 AM
All mainly related to opening and closing of keyboard. 1) Keyboard used to get stuck sometimes and didn't hide when clicked outside 2) Keyboard doesn't show up when TextField focused 3) It wasn't possible to pre-focus a TextField prior alpha11. It's now possible with the snippet I shared. 4) I'm not sure whether we do have to explicitly use
imePadding()
or
navigationBarsWithImePadding()
to prevent TextField from getting hidden by the Keyboard but now I'm using it everywhere I've
TextField
. This wasn't a case with native xml layouts.
softInputMode=adjustResize
in AndroidManifest and
fitsSystemWindow=true
used to do the job for us.
a

allan.conda

02/02/2021, 9:23 AM
omg, that’s good news! We’ve been tracking these issues for a long time and gives a bad impression. I’m excited to update. Any critical issues when you updated?
k

Kshitij Patil

02/02/2021, 9:34 AM
No issues so far.
🙏 1
s

Shakil Karim

02/14/2021, 10:01 AM
@Adam Powell Is this the valid case of using DisposableEffect? ColorToApply : Color which will change colorPrimary: Default color
Copy code
DisposableEffect(ColorToApply) {
    systemUIController.setStatusBarColor(ColorToApply)
    onDispose {
        systemUIController.setStatusBarColor(colorPrimary)
    }
}
a

Adam Powell

02/14/2021, 2:29 PM
That'll probably get you pretty far. For something library-grade I'd probably try to give that sysuiController class an add/dispose mechanism with some sort of disambiguation for cases when more than one of these snippets is present in the composition at the same time. There would be cases where you wouldn't want to go back to the default, but instead you'd want to fall back to the other contributor.
e.g.: Enter A(red) Enter B(blue) // what color is the bar now and why? Leave A or B // what color is the bar now and why?
This is where this kind of inverted control, where potentially multiple children in the composition contribute something to a single parent element, needs to be thought through carefully. Often the first question should be, "do I really need this?" and if you can have one piece of code consuming the various states that might affect the status bar color and emitting it directly in one place, things can be simpler.
1
s

Shakil Karim

02/18/2021, 5:27 PM
Thank you, for detail answer, I agree it would be problem if multiple composable use this code at same time, but in my case only screen level composable uses this snippet.