android - 我可以在 Jetpack Compose 中使用 Remember 来包装 Modifier 吗?

标签 android android-jetpack-compose

为了在 compose 函数之间共享设置,我创建了一个 class AboutState() 和一个 compose fun RememberAboutState() 来保存设置。

我不知道是否可以在解决方案中使用 remember 包装 Modifier

代码 A 可以很好地工作,但我不知道当我用 remember 包装 Modifier 时是否会导致问题,我认为 Modifier 是特殊类,它是基于多态调用的。

代码A

@Composable
fun ScreenAbout(
    aboutState: AboutState =  rememberAboutState()
) {
   Column() {
       Hello(aboutState)
       World(aboutState)
   }
}

@Composable
fun Hello(
    aboutState: AboutState
) {
    Text("Hello",aboutState.modifier)
}

@Composable
fun World(
    aboutState: AboutState
) {
    Text("World",aboutState.modifier)
}

class AboutState(
    val textStyle: TextStyle,
    val modifier: Modifier=Modifier
) {
    val rowSpace: Dp = 20.dp
}

@Composable
fun rememberAboutState(): AboutState {
    val aboutState = AboutState(
        textStyle = MaterialTheme.typography.body1.copy(
            color=Color.Red
        ),
        modifier=Modifier.padding(start = 80.dp)
    )
    return remember {
        aboutState
    }
}

最佳答案

将修饰符传递给类不会有问题。您上面实际定义的内容,即使名为 State,也不是充当 State 的类,我更合适地将其命名为 HelloStyle , HelloDefaults.style()

将类命名为 XState 会更合适什么时候应该有内部或公共(public)MutableState可以触发重组,或者您可以获得当前的 StateComposableModifier由于变化。它不应该只包含样式,还应该包含状态机制来更改或观察 Composble 的状态,例如 ScrollStatePagerState .

当您拥有状态包装器对象时,拥有有状态修饰符或具有内存的修饰符或具有 Compose 范围的修饰符的常见方法是使用 Modifier.composed{}并将 State 传递给 Modifier,而不是相反。

When do you need Modifier.composed { ... }?

fun Modifier.composedModifier(aboutState: AboutState) = composed(
    factory = {
        val color = remember { getRandomColor() }
        aboutState.color = color
        Modifier.background(aboutState.color)
    }
)

在此示例中,即使 getRandomColor 不实用,也会在重组时创建一次并使用相同的颜色。

我用来放大这个的缩放修改器library是这样的

fun Modifier.zoom(
    key: Any? = Unit,
    consume: Boolean = true,
    clip: Boolean = true,
    zoomState: ZoomState,
    onGestureStart: ((ZoomData) -> Unit)? = null,
    onGesture: ((ZoomData) -> Unit)? = null,
    onGestureEnd: ((ZoomData) -> Unit)? = null
) = composed(
    factory = {
        val coroutineScope = rememberCoroutineScope()

        // Current Zoom level
        var zoomLevel by remember { mutableStateOf(ZoomLevel.Min) }

           // Rest of the code

    },
    inspectorInfo = {
        name = "zoom"
        properties["key"] = key
        properties["clip"] = clip
        properties["consume"] = consume
        properties["zoomState"] = zoomState
        properties["onGestureStart"] = onGestureStart
        properties["onGesture"] = onGesture
        properties["onGestureEnd"] = onGestureEnd
    }
)

另一个实际的例子是使用 RememberCoroutineScope() 的 Modifier.scroll,您也可以记住对象,以免在重组时实例化另一个对象

@OptIn(ExperimentalFoundationApi::class)
private fun Modifier.scroll(
    state: ScrollState,
    reverseScrolling: Boolean,
    flingBehavior: FlingBehavior?,
    isScrollable: Boolean,
    isVertical: Boolean
) = composed(
    factory = {
        val overscrollEffect = ScrollableDefaults.overscrollEffect()
        val coroutineScope = rememberCoroutineScope()
        // Rest of the code
    },
    inspectorInfo = debugInspectorInfo {
        name = "scroll"
        properties["state"] = state
        properties["reverseScrolling"] = reverseScrolling
        properties["flingBehavior"] = flingBehavior
        properties["isScrollable"] = isScrollable
        properties["isVertical"] = isVertical
    }
)

关于android - 我可以在 Jetpack Compose 中使用 Remember 来包装 Modifier 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73527364/

相关文章:

android - 如何在 Eclipse 中刷新项目

android - 如何在 Jetpack Compose 中像下面的布局一样实现波纹或波浪或雷达加载

android - 无法将 'Column' 内联方法调用到 Jetpack compose 中的本地最终乐趣 <anonymous>()

android - 如何在 Jetpack Compose 中为动态列表的元素设置动画?

android - 在 android 上加载纹理,图像只是黑白噪声

android - 通过 Kotlin Coroutine Flow 压缩网络请求

Android: <include> 与 RippleEffect & StateListAnimator

android - 如何在实时 android 设备(智能手机等)上连接和配置 android studio?

android-jetpack-compose - ScalingLazyColumn (Jetpack Compose Wear OS) 默认行为中的错误

android - 监听 Jetpack Compose 中的 ModalBottomSheetLayout 状态变化