Status Update
Comments
il...@google.com <il...@google.com> #2
We have some support in androidx.compose.ui.autofill
Leaving this bug open in case Ralston wants to add more info
il...@google.com <il...@google.com> #3
I found an example
D/Autofill Status: Autofill popup isn't shown because autofill is not available.
Did you set up autofill?
1. Go to Settings > System > Languages&input > Advanced > Autofill Service
2. Pick a service
Did you add an account?
1. Go to Settings > System > Languages&input > Advanced
2. Click on the settings icon next to the Autofill Service
3. Add your account
Is this a bug on your side or do the app developers of these password managers need to change their implementation?
il...@google.com <il...@google.com>
ap...@google.com <ap...@google.com> #6
ap...@google.com <ap...@google.com> #7
ap...@google.com <ap...@google.com> #8
I setup this modifier:
@OptIn(ExperimentalComposeUiApi::class)
fun Modifier.autofill(
autofillTypes: List<AutofillType>,
onFill: ((String) -> Unit),
) = composed {
val autofill = LocalAutofill.current
val autofillNode = AutofillNode(onFill = onFill, autofillTypes = autofillTypes)
LocalAutofillTree.current += autofillNode
this.onGloballyPositioned {
autofillNode.boundingBox = it.boundsInWindow()
}.onFocusChanged { focusState ->
autofill?.run {
if (focusState.isFocused) {
requestAutofillForNode(autofillNode)
} else {
cancelAutofillForNode(autofillNode)
}
}
}
}
And use it like this:
val emailState = remember { EmailState() }
Email(
modifier = Modifier.autofill(
autofillTypes = listOf(
AutofillType.Username,
AutofillType.EmailAddress
),
onFill = { emailState.text = it },
),
emailState = emailState,
onImeAction = { onForgotPasswordSubmitted(emailState.text) }
)
With these steps, autofill works for me.
sn...@gmail.com <sn...@gmail.com> #10
Works perfectly fine on the latest stable and alpha versions. Did you check in my second comment if you enabled everything?
il...@google.com <il...@google.com> #11
I believe so?
I copied the modifier and then used
modifier = Modifier.autofill(
autofillTypes = listOf(
AutofillType.Username,
AutofillType.EmailAddress
),
onFill = { emailState.text = it },
)
on my text field.
ro...@theorytank.com <ro...@theorytank.com> #12
il...@google.com <il...@google.com> #13
The auto-filling works for me with the latest alpha version, but I'm never presented with the save dialog though.
I am having exactly same problem. Autofill works, but the Save dialog is never shown...
[Deleted User] <[Deleted User]> #14
Any updates on this? I can't get LastPass to display at all. I can ONLY get the Google Auto-fill service to work
Description
Jetpack Compose release version: Compose alpha11 Android Studio Build: Arctic Fox Canary 4
There appears to be a number of issues with inflating a fragment by using
AndroidViewBinding
:If you use
FragmentContainerView
, the fragment appears the first time the container is inflated, but later times it does not appear.If you use
<fragment>
, the fragment appears the first time the fragment is inflated, but will crash if you try to re-inflate the same layout a second time. Rotating your screen or otherwise recreating the Activity will reset it so that the first inflation worksIn both cases, removing the
AndroidViewBinding
from your compose hierarchy does not remove the underlyingFragment
from theFragmentManager
. This means that the Fragment remains in memory forever afterwards.I've attached a sample project that contains three situation (using
FragmentContainerView
, using<fragment>
, and manually doing aFragmentTransaction
in Compose code) and a 'Show' button of each that lets you confirm what happens when theAndroidViewBinding
is removed from the hierarchy.My investigation lead to a couple of discoveries:
After a configuration change, the whole activity and the
FragmentManager
has moved to theRESUMED
state before the compose hierarchy is processed andAndroidViewBinding
is able to inflate its container. This means the original fragment added via the inflatedFragmentContainerView
has already had its view created and moved to theRESUMED
state before the container exists. Thus, the transition betweenonCreateView()
andonViewCreated()
where the view is attached to its container has already passed when theAndroidViewBinding
creates the container.The
<fragment>
tag added fragment never goes above theCREATED
state on its own - Fragments is correctly stopping it from going higher thanCREATED
during the inflation, but because Compose is inflating it after the FragmentManager has already moved throughRESUMED
, the usual moving of state for<fragment>
inflated fragments doesn't happen. Doing anotherFragmentTransaction
on a different fragment/container moves it toSTARTED
, but it never moves toRESUMED
as no FragmentTransactions on that container are pending (and moving toRESUMED
is done at a container by container basis) as the<fragment>
tag doesn't actually do aFragmentTransaction
.It is expected that when a composable is removed from the hierarchy that any internal state is thrown out (that's why you'd normally hoist state you want to save). Because Fragments are never removed when the
AndroidViewBinding
is removed from the hierarchy, the Fragments keep their state over a removal / addition of a new element that happens to inflate that same layout.