gpt4 book ai didi

android - Jetpack 撰写 : Make full-screen (absolutely positioned) component

转载 作者:行者123 更新时间:2023-12-04 23:38:53 25 4
gpt4 key购买 nike

我怎样才能在渲染树全屏的深处进行可组合,类似于 Dialog可组合的作品?
例如,当用户单击图像时,它会在不更改当前路线的情况下显示图像的全屏预览。
我可以用 position: absolute 在 CSS 中做到这一点或 position: fixed但是我将如何在 Jetpack Compose 中执行此操作?甚至可能吗?
一种解决方案是在树的顶部有一个可组合对象,可以将另一个可组合对象作为参数从树的其他位置传递,但这听起来有点困惑。肯定有更好的方法。

最佳答案

据我所知,您希望能够从嵌套层次结构中绘制而不受父约束的限制。
我们遇到了类似的问题,并查看了诸如 Popup 之类的 Composables 的实现方式。 , DropDownDialog功能。
他们所做的是添加一个全新的ComposeViewWindow .
因此,它们基本上是从空白 Canvas 开始的。
通过使其透明,看起来 Dialog/Popup/DropDown 出现在顶部。
不幸的是,我们找不到可以为我们提供仅添加新 ComposeView 功能的 Composable。到Window所以我们复制了相关部分并进行了以下操作。

@Composable
fun FullScreen(content: @Composable () -> Unit) {
val view = LocalView.current
val parentComposition = rememberCompositionContext()
val currentContent by rememberUpdatedState(content)
val id = rememberSaveable { UUID.randomUUID() }

val fullScreenLayout = remember {
FullScreenLayout(
view,
id
).apply {
setContent(parentComposition) {
currentContent()
}
}
}

DisposableEffect(fullScreenLayout) {
fullScreenLayout.show()
onDispose { fullScreenLayout.dismiss() }
}
}

@SuppressLint("ViewConstructor")
private class FullScreenLayout(
private val composeView: View,
uniqueId: UUID
) : AbstractComposeView(composeView.context) {

private val windowManager =
composeView.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager

private val params = createLayoutParams()

override var shouldCreateCompositionOnAttachedToWindow: Boolean = false
private set

init {
id = android.R.id.content
ViewTreeLifecycleOwner.set(this, ViewTreeLifecycleOwner.get(composeView))
ViewTreeViewModelStoreOwner.set(this, ViewTreeViewModelStoreOwner.get(composeView))
ViewTreeSavedStateRegistryOwner.set(this, ViewTreeSavedStateRegistryOwner.get(composeView))

setTag(R.id.compose_view_saveable_id_tag, "CustomLayout:$uniqueId")
}

private var content: @Composable () -> Unit by mutableStateOf({})

@Composable
override fun Content() {
content()
}

fun setContent(parent: CompositionContext, content: @Composable () -> Unit) {
setParentCompositionContext(parent)
this.content = content
shouldCreateCompositionOnAttachedToWindow = true
}

private fun createLayoutParams(): WindowManager.LayoutParams =
WindowManager.LayoutParams().apply {
type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
token = composeView.applicationWindowToken
width = WindowManager.LayoutParams.MATCH_PARENT
height = WindowManager.LayoutParams.MATCH_PARENT
format = PixelFormat.TRANSLUCENT
flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
}

fun show() {
windowManager.addView(this, params)
}

fun dismiss() {
disposeComposition()
ViewTreeLifecycleOwner.set(this, null)
windowManager.removeViewImmediate(this)
}
}
这是一个如何使用它的示例
@Composable
internal fun Screen() {
Column(
Modifier
.fillMaxSize()
.background(Color.Red)
) {
Text("Hello World")

Box(Modifier.size(100.dp).background(Color.Yellow)) {
DeeplyNestedComposable()
}
}
}

@Composable
fun DeeplyNestedComposable() {
var showFullScreenSomething by remember { mutableStateOf(false) }
TextButton(onClick = { showFullScreenSomething = true }) {
Text("Show full screen content")
}

if (showFullScreenSomething) {
FullScreen {
Box(
Modifier
.fillMaxSize()
.background(Color.Green)
) {
Text("Full screen text", Modifier.align(Alignment.Center))
TextButton(onClick = { showFullScreenSomething = false }) {
Text("Close")
}
}
}
}
}
黄色框设置了一些约束,这将阻止 Composables 从内部绘制到其边界之外。
enter image description here

关于android - Jetpack 撰写 : Make full-screen (absolutely positioned) component,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68460291/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com