You can find a sample project to reproduce the issue on Github
Button click works, but showing/ hiding the "Text" inside Column is not working when using InputMethodService
@Composable
fun CustomKeyboard(imeService: MyIMEService) {
var isShow by remember { mutableStateOf(true)}
Column {
if(isShow) { Text(text = "Good Luck", color = Color.Green) } // <- not working here!
Button(onClick = {
isShow = !isShow
imeService.doSomethingWith("A")
}) {
Text(text = "Test Show/Hide")
}
}
}
The problem starts after updating savedstate-ktx:1.2.0 for the method setViewTreeSavedStateRegistryOwner().
For easier understanding details of InputMethodService here
class ComposeKeyboardView(private val imeService: MyIMEService) : AbstractComposeView(imeService) {
@Composable
override fun Content() {
CustomKeyboard(imeService)
}
}
class MyIMEService : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner {
override fun onCreateInputView(): View {
val view = ComposeKeyboardView(this)
window!!.window!!.decorView.let { decorView ->
ViewTreeLifecycleOwner.set(decorView, this)
ViewTreeViewModelStoreOwner.set(decorView, this)
decorView.setViewTreeSavedStateRegistryOwner(this)
}
return view
}
fun doSomethingWith(mData: String) {
currentInputConnection?.commitText(mData, 1)
}
private val _lifecycleRegistry: LifecycleRegistry by lazy { LifecycleRegistry(this) }
private val _store by lazy { ViewModelStore() }
override fun getLifecycle(): Lifecycle = _lifecycleRegistry
override fun getViewModelStore(): ViewModelStore = _store
override val savedStateRegistry: SavedStateRegistry = SavedStateRegistryController.create(this).savedStateRegistry
private fun handleLifecycleEvent(event: Lifecycle.Event) =
_lifecycleRegistry.handleLifecycleEvent(event)
@CallSuper
override fun onCreate() {
super.onCreate()
// You must call performAttach() before calling performRestore(Bundle)
savedStateRegistry.performAttach(lifecycle)
savedStateRegistry.performRestore(null)
handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
}
@CallSuper
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
stopSelf()
}
@CallSuper
override fun onDestroy() {
super.onDestroy()
handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
}
}
Source: This project is based on Yannick's and Simsim's answer.