Gab*_*lie 5 android kotlin android-jetpack-compose compose-recomposition
我正在尝试创建一个覆盖层并将视图附加到 WindowManager,我已经通过创建一个实现 Lifecycle/ViewModelStore/SavedStateRegistry Owner 的类来设法做到这一点。\n但由于某种原因,每当我尝试显示对话框/更改时以任何方式使用 MutableState 或 MutableStateFlow 重组的 UI 都不会触发。
\n有没有人尝试过做这样的事情并设法找到触发重组的解决方案?
\n这就是我尝试创建和插入视图的方式:
\n@SuppressLint("InflateParams")\nfun showOverlay() {\n synchronized(lock) {\n if (overlay != null || overlay?.parent != null) {\n return\n }\n val viewModel = OverlayViewModel(context.applicationContext as Application)\n var scope: CoroutineScope? = null\n overlay = ComposeView(context).apply {\n setContent {\n Overlay(viewModel)\n }\n }\n drawOverLifecycleOwner = DrawOverLifecycleOwner()\n drawOverLifecycleOwner?.attachToDecorView(overlay)\n val params =\n WindowManager.LayoutParams(\n WindowManager.LayoutParams.MATCH_PARENT,\n WindowManager.LayoutParams.MATCH_PARENT,\n WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,\n WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,\n PixelFormat.TRANSLUCENT\n )\n params.gravity = Gravity.TOP or Gravity.START\n Log.i("ScreenLocker", "Inserting overlay")\n ContextCompat.getMainExecutor(context).execute {\n drawOverLifecycleOwner?.onCreate()\n windowManager.addView(overlay, params)\n }\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n这是自定义的 LifecycleOwner:
\nimport android.view.View\nimport androidx.lifecycle.*\nimport androidx.savedstate.SavedStateRegistry\nimport androidx.savedstate.SavedStateRegistryController\nimport androidx.savedstate.SavedStateRegistryOwner\nimport androidx.savedstate.ViewTreeSavedStateRegistryOwner\n\nclass DrawOverLifecycleOwner : LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner {\n\n fun onCreate() {\n savedStateRegistryController.performRestore(null)\n lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)\n }\n\n fun onResume() {\n lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)\n }\n\n fun onPause() {\n lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)\n }\n\n fun onDestroy() {\n lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)\n savedStateRegistryController.performSave(Bundle())\n store.clear()\n }\n\n /**\n Compose uses the Window's decor view to locate the\n Lifecycle/ViewModel/SavedStateRegistry owners.\n Therefore, we need to set this class as the "owner" for the decor view.\n */\n fun attachToDecorView(decorView: View?) {\n if (decorView == null) return\n\n ViewTreeLifecycleOwner.set(decorView, this)\n ViewTreeViewModelStoreOwner.set(decorView, this)\n ViewTreeSavedStateRegistryOwner.set(decorView, this)\n }\n\n // LifecycleOwner methods\n private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)\n\n override fun getLifecycle(): Lifecycle = lifecycleRegistry\n\n // ViewModelStore methods\n private val store = ViewModelStore()\n override fun getViewModelStore(): ViewModelStore = store\n\n // SavedStateRegistry methods\n private val savedStateRegistryController = SavedStateRegistryController.create(this)\n override val savedStateRegistry: SavedStateRegistry\n get() = savedStateRegistryController.savedStateRegistry\n}\n
Run Code Online (Sandbox Code Playgroud)\n这是叠加层:
\n@Composable\nfun Overlay(viewModel: OverlayViewModel = viewModel()) {\n val showDialog = remember { MutableStateFlow(false) }\n AppTheme {\n Logger.info("Recomposition triggered")\n ConstraintLayout(\n modifier = Modifier\n .fillMaxSize()\n .background(Color.Black)\n ) {\n val (dialog) = createRefs()\n Box(modifier = Modifier.fillMaxSize()) {\n Text(\n modifier = Modifier\n .align(Alignment.TopEnd)\n .padding(top = 25.dp, end = 15.dp),\n text = "\xc2\xa9 2022",\n color = Color.White\n )\n Column(\n modifier = Modifier.align(Alignment.Center),\n horizontalAlignment = Alignment.CenterHorizontally\n ) {\n Image(\n modifier = Modifier\n .fillMaxWidth()\n .padding(15.dp),\n painter = painterResource(R.drawable.logo),\n contentDescription = "Logo",\n contentScale = ContentScale.Fit,\n )\n Text(\n modifier = Modifier.padding(bottom = 25.dp),\n text = "Overlay Text",\n textAlign = TextAlign.Center,\n color = Color.White,\n fontWeight = FontWeight.Bold,\n style = MaterialTheme.typography.headlineMedium\n )\n LazyRow {\n items(LockService.whitelistedApps) { app ->\n Button(\n onClick = { viewModel.launchApp(app) },\n colors = ButtonDefaults.buttonColors(\n containerColor = Color.Transparent\n )\n ) {\n Column(horizontalAlignment = Alignment.CenterHorizontally) {\n viewModel.getPackageIcon(app)?.apply {\n Image(\n this.asImageBitmap(),\n contentDescription = "App Icon"\n )\n }\n Text(\n text = viewModel.getPackageLabel(app),\n color = Color.White\n )\n }\n }\n }\n }\n }\n IconButton(\n modifier = Modifier\n .align(Alignment.BottomStart)\n .padding(bottom = 15.dp, start = 15.dp),\n onClick = {\n Logger.info("Trying to show dialog, showDialogValue = ${showDialog.value}")\n showDialog.tryEmit(true)\n }\n ) {\n Icon(\n imageVector = Icons.Default.Info,\n contentDescription = "Info Dialog Icon",\n tint = Color.White\n )\n }\n }\n if (showDialog.collectAsState().value) {\n InfoDialog(showDialog, Modifier.constrainAs(dialog) {\n top.linkTo(parent.top)\n bottom.linkTo(parent.bottom)\n start.linkTo(parent.start)\n end.linkTo(parent.end)\n })\n }\n }\n }\n}\n\n@Preview\n@Composable\nfun OverlayPreview() {\n AppTheme {\n Overlay(OverlayViewModel(Application()))\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
小智 5
嘿,我发现我的实现中存在问题,可能与您的问题相同。
当你强制将lifecycleOwner设置为ComposeView时,你是否也设置了ON_START事件?在我的系统中,当我完成可组合项开始响应即将到来的新状态时,它丢失了。
val viewModelStore = ViewModelStore()
lifecycleOwner.performRestore(null)
lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START)
ViewTreeLifecycleOwner.set(composeView, lifecycleOwner)
ViewTreeViewModelStoreOwner.set(composeView) { viewModelStore }
it.setViewTreeSavedStateRegistryOwner(lifecycleOwner)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1326 次 |
最近记录: |