kotlin 有没有办法让状态管理为Jetpack合成中的抽象合成视图工作?

mxg2im7a  于 2022-12-13  发布在  Kotlin
关注(0)|答案(1)|浏览(116)

我目前正在创建一个键盘,它需要能够从我创建的视图模型中获取数据。
当任何类型的状态被改变时,键盘不能被重新组合的事实引起了问题。
是否有一种方法能够在Abstract Compose View的任何状态发生更改时实现重组/更新?
这是我为InputMethodService使用的代码,以供参考

class IMEService:
    InputMethodService(),
    LifecycleOwner,
    ViewModelStoreOwner,
    SavedStateRegistryOwner {
    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)
    }

    lateinit var viewModel: RepoViewModel
    override fun onCreateInputView(): View {
        val app = (application as Nitroless)
        val view = ComposeKeyboardView(this)
        viewModel = ViewModelProvider(this, RepoViewModelFactory(app.repository, app.communityReposRepository)).get(RepoViewModel::class.java)

        this.attachToDecorView(
            window?.window?.decorView
        )
        return view
    }

    fun attachToDecorView(decorView: View?) {
        if (decorView == null) return

        ViewTreeLifecycleOwner.set(decorView, this)
        ViewTreeViewModelStoreOwner.set(decorView, this)
        decorView.setViewTreeSavedStateRegistryOwner(this)
    }
}

正如你所看到的,我已经将视图模型添加为一个Provider onCreateInputView()函数。问题不是我不能访问它,问题是我似乎不能更新ComposeKeyboardView。
这是我的合成键盘视图-

class ComposeKeyboardView(context: Context): AbstractComposeView(context) {
    @Composable
    override fun Content() {
        val viewModel: RepoViewModel = (context as IMEService).viewModel

        KeyboardScreen()
    }
}
vohkndzv

vohkndzv1#

我找到了一个解决方案,我在查看InputMethodService的文档时发现了setInputView(查看:View?),这样我就可以强制在键盘上刷新compose视图。
所以我就这么做了
(context as IMEService).setInputView(ComposeKeyboardVie(context))
我还找到了一种在IMEService类中使用Hilt的方法,即对服务使用@AndroidEntryPoint注解,并使用@Inject注解注入视图模型。

@AndroidEntryPoint
class IMEService:
    InputMethodService(),
    LifecycleOwner,
    ViewModelStoreOwner,
    SavedStateRegistryOwner {
    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)
    }

    @Inject
    lateinit var repoViewModel: RepoViewModel

    override fun onCreateInputView(): View {
        val view = ComposeKeyboardView(this)

        this.attachToDecorView(
            window?.window?.decorView
        )
        return view
    }

    fun attachToDecorView(decorView: View?) {
        if (decorView == null) return

        ViewTreeLifecycleOwner.set(decorView, this)
        ViewTreeViewModelStoreOwner.set(decorView, this)
        decorView.setViewTreeSavedStateRegistryOwner(this)
    }
}

在我刚刚添加的应用程序模块中

@Singleton
@Provides
fun providesRepoViewModel(repoDatabaseDao: RepoDatabaseDao, communityReposRepository: CommunityReposRepository) = RepoViewModel(repository = RepoRepository(repoDatabaseDao), communityReposRepository = communityReposRepository)

相关问题