如何在 WindowManager.addView 中使用 Jetpack Compose

这篇具有很好参考价值的文章主要介绍了如何在 WindowManager.addView 中使用 Jetpack Compose。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

如何在 WindowManager.addView 中使用 Jetpack Compose

一、引出问题

Android 开发中,很常见的一个场景,通过 WindowManager.addView() 添加一个 View 到屏幕上。Android 最新的视图框架 Jetpack Compose,如何应用进来。这个被添加的 View 如何使用 Compose 编写视图呢?

二、探究问题

有的朋友肯定会马上想到使用 ComposeView 作为桥梁。没错,WindowManager.addView 方法,就接收一个 View 类型的参数。那肯定是要借助 ComposeView 了。但是,经过试验,直接使用 ComposeView 是行不通的。
看代码:

val params = WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
    PixelFormat.TRANSLUCENT
)

val composeView: ComposeView = ComposeView(this).apply {
    setContent {
        Text(text = "I'm be added")
    }
}

windowManager.addView(composeView, params)

上面代码,编译没有问题,运行时会报错:

FATAL EXCEPTION: main
Process: xxxxxxxx
java.lang.IllegalStateException: ViewTreeLifecycleOwner not found from androidx.compose.ui.platform.ComposeView{8285855 V.E...... ......I. 0,0-0,0}
    at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer(WindowRecomposer.android.kt:352)
    at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer$default(WindowRecomposer.android.kt:325)
    at androidx.compose.ui.platform.WindowRecomposerFactory$Companion$LifecycleAware$1.createRecomposer(WindowRecomposer.android.kt:168)
    at androidx.compose.ui.platform.WindowRecomposerPolicy.createAndInstallWindowRecomposer$ui_release(WindowRecomposer.android.kt:224)
    at androidx.compose.ui.platform.WindowRecomposer_androidKt.getWindowRecomposer(WindowRecomposer.android.kt:300)
    at androidx.compose.ui.platform.AbstractComposeView.resolveParentCompositionContext(ComposeView.android.kt:244)
    at androidx.compose.ui.platform.AbstractComposeView.ensureCompositionCreated(ComposeView.android.kt:251)
    at androidx.compose.ui.platform.AbstractComposeView.onAttachedToWindow(ComposeView.android.kt:283)
    at android.view.View.dispatchAttachedToWindow(View.java:22065)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3553)
    ...

看这个错误信息:
应该是从 ComposeView 中没有找到 ViewTreeLifecycleOwner, 其实很好理解。 View 的生命周期依赖于 ViewTreeLifecycleOwner, ComposeView 依赖于一个 ViewCompositonStrategy。核心问题是,ComposeView 需要一个 Lifecycle。

三、解决问题

有了思路自然就尝试解决问题。
首先定义一个 LifecycleOwner ,

import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.savedstate.SavedStateRegistry
import androidx.savedstate.SavedStateRegistryController
import androidx.savedstate.SavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner

class MyComposeViewLifecycleOwner:
    LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner {

    private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
    private val savedStateRegistryController = SavedStateRegistryController.create(this)
    private val store = ViewModelStore()

    override val lifecycle: Lifecycle
        get() = lifecycleRegistry
    override val savedStateRegistry: SavedStateRegistry
        get() = savedStateRegistryController.savedStateRegistry
    override val viewModelStore: ViewModelStore
        get() = store


    fun onCreate() {
        savedStateRegistryController.performRestore(null)
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
    }

    fun onStart() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
    }

    fun onResume() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
    }

    fun onPause() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    }

    fun onStop() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
    }

    fun onDestroy() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        store.clear()
    }

    /**
     * Compose uses the Window's decor view to locate the
     * Lifecycle/ViewModel/SavedStateRegistry owners.
     * Therefore, we need to set this class as the "owner" for the decor view.
     */
    fun attachToDecorView(decorView: View?) {
        decorView?.let {
            it.setViewTreeViewModelStoreOwner(this)
            it.setViewTreeLifecycleOwner(this)
            it.setViewTreeSavedStateRegistryOwner(this)
        } ?: return
    }
}

再看看使用:

private var lifecycleOwner: MyComposeViewLifecycleOwner? = null

val params = WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
    PixelFormat.TRANSLUCENT
)

val composeView: ComposeView = ComposeView(this).apply {
    setContent {
        Text(text = "I'm be added")
    }
}


// 注意,在 调用 addView 之前:
lifecycleOwner = MyComposeViewLifecycleOwner().also {
                        it.onCreate() // 注意
                        it.attachToDecorView(composeView)
                    }
windowManager.addView(composeView, params)




windowManager.removeViewImmediate(composeView)
lifecycleOwner?.onDestroy()
lifecycleOwner = null

OK,再次运行。成功~文章来源地址https://www.toymoban.com/news/detail-760478.html

到了这里,关于如何在 WindowManager.addView 中使用 Jetpack Compose的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在 Jetpack Compose 中使用 BottomAppBar

    Jetpack Compose 是一个现代化的、声明式的 UI 工具包,它使我们能够更方便地构建 Android 的用户界面。本篇文章将介绍如何在 Jetpack Compose 中使用 BottomAppBar 来创建底部应用栏。 BottomAppBar 是一个在屏幕底部的应用栏,提供了在 Material Design 风格的应用中实现导航和执行操作的一种

    2024年02月13日
    浏览(43)
  • Jetpack Compose 中组件使用教程(比较全面)

    在本文中,我们将学习 Jetpack Compose,这是一个用于构建原生 UI 的现代工具包。 通过这个完整的教程,我们将学习如何使用 Text、TextField、Preview、Column、Row、Button、Card、AlertDialog、MaterialDesign 元素等。因此,事不宜迟,让我们开始创建一个 Jetpack Compose 项目。因此,本章节是

    2024年02月10日
    浏览(39)
  • Android Jetpack Compose之RadioGroup的使用

    Android Jetpack Compose是一个现代化的UI工具包,帮助开发者以声明式的方式构建出美观且功能强大的Android应用。在本文中,我们将详细介绍其中的一个重要组件—— RadioGroup 。 一. RadioGroup简介 Jetpack Compose中并没有像传统View系统中那样直接提供 RadioGroup ,但我们可以很方便地通

    2024年02月06日
    浏览(53)
  • 使用 Jetpack Compose 实现一个计算器APP

    在上一篇文章中,我们说到打算使用 compose 实现一个计算器 APP,最开始打算做一个经典的 LCD 基础计算器,后来觉得好像没啥特色,最终决定还是改成仿微软计算器。 不过,微软计算器的功能太多了,仿制的工程量不小,所以我打算只仿我认为最核心的两个模式:标准模式和

    2024年02月05日
    浏览(62)
  • Android Jetpack Compose中使用字段验证的方法

    数据验证是创建健壮且用户友好的Android应用程序的关键部分。随着现代UI工具包Jetpack Compose的引入,处理字段验证变得更加高效和直观。在这篇文章中,我们将探讨如何在Android应用中使用Jetpack Compose进行字段验证。 字段验证是确保用户在各种输入字段中输入的数据符合特定

    2024年02月11日
    浏览(50)
  • 使用 CameraX 在 Jetpack Compose 中构建相机 Android 应用程序

    CameraX 是一个 Jetpack 库,旨在帮助简化相机应用程序的开发。 [camerax官方文档] https://developer.android.com/training/camerax CameraX的几个用例: Image Capture Video Capture Preview Image analyze 具体如何使用相关用例,请查看上面的官方链接。 下面仅就视频录制用例来叙述相关实现流程。 添加

    2024年02月06日
    浏览(65)
  • 在Jetpack Compose中使用ExoPlayer实现直播流和音频均衡器

    ExoPlayer与Media3的能力结合,为Android应用程序播放多媒体内容提供了强大的解决方案。在本教程中,我们将介绍如何设置带有Media3的ExoPlayer来支持使用M3U8 URL进行直播流。此外,我们还将探讨如何集成音频均衡器,为用户提供个性化的音频体验。 使用ExoPlayer进行直播流涉及到利

    2024年02月04日
    浏览(50)
  • Jetpack Compose 深入探索系列四: Compose UI

    通过 Compose runtime 集成 UI Compose UI 是一个 Kotlin 多平台框架。它提供了通过可组合函数发出 UI 的构建块和机制。除此之外,这个库还包括 Android 和 Desktop 源代码,为 Android 和 Desktop 提供集成层。 JetBrains积极维护Desktop代码库,而Google维护Android和通用代码库。Android和Desktop源代码

    2024年02月12日
    浏览(48)
  • Jetpack Compose(6)——动画

    目录 一、低级别动画 API 1.1 animate*AsState 1.2 Animatable 1.3 Transition 动画 1.3.1 updateTransition 1.3.2 createChildTransition 1.3.3 封装并复用 Transition 动画 1.4 remeberInfiniteTransition —— 无限循环的 transition 动画 1.5 小结 二、Android Studio 对 Compose 动画调试的支持 三、AnimationSpec 动画规格 3.1 Sprin

    2024年04月26日
    浏览(32)
  • Jetpack Compose(4)——重组

    目录 一、状态变化 1.1 状态变化是什么 1.2 mutableStateListOf 和 mutableStateMapOf 二、重组的特性 2.1 Composable 重组是智能的 2.2 Composable 会以任意顺序执行 2.3 Composable 会并发执行 2.4 Composable 会反复执行 2.5 Composable 的执行是“乐观”的 三、重组范围 四、参数类型的稳定性 4.1 稳定和不

    2024年04月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包