Android Compose 中基于特定条件的链接修饰符

问题描述 投票:0回答:6

我想以这样的方式应用修饰符:如果提供了宽度,则应使用提供的宽度,否则使用可用的最大宽度。

我按照以下方式应用修改器,但结果并不符合预期。 视图宽度变得混乱。在此请求指导。

val myModifier = Modifier.padding(
    start = 4.dp, end = 4.dp, top = 8.dp, bottom = 8.dp
)

if (viewWidth == null)
    myModifier.then(Modifier.fillParentMaxWidth(1f))
else
    myModifier.then(Modifier.width(viewWidth))

myModifier.then(
    Modifier.height(viewHeight ?: 100.dp)
        .clickable(onClick = { listener.onItemClick(item) })
)
android kotlin android-jetpack android-jetpack-compose
6个回答
56
投票

您可以通过扩展函数创建条件修饰符:

fun Modifier.conditional(condition : Boolean, modifier : Modifier.() -> Modifier) : Modifier {
    return if (condition) {
        then(modifier(Modifier))
    } else {
        this
    }
}

这可以让您在

conditional
块中链接修改器,如下所示:

val applySpecialBackground : Boolean = [...]
Column(
    modifier = Modifier
        .fillMaxWidth()
        .conditional(applySpecialBackground) {
            background(Color.Red)
        }
        .padding(16.dp)

) { [...] }

仅当条件为

true
时才会应用条件修饰符。

如果您需要

false
情况的修饰符,只需链接第二个否定条件即可。

val applySpecialBackground : Boolean = [...]
Column(
    modifier = Modifier
        .fillMaxWidth()
        .conditional(applySpecialBackground) {
            background(Color.Red)
        }
        .conditional(!applySpecialBackground) {
            background(Color.Blue)
        }
        .padding(16.dp)

) { [...] }

如果您感觉超级喜欢,您还可以向扩展函数添加可选的负案例。

fun Modifier.conditional(
    condition: Boolean,
    ifTrue: Modifier.() -> Modifier,
    ifFalse: (Modifier.() -> Modifier)? = null
): Modifier {
    return if (condition) {
        then(ifTrue(Modifier))
    } else if (ifFalse != null) {
        then(ifFalse(Modifier))
    } else {
        this
    }
}

如果您的条件为假,这将为您提供一个单独的参数:

val applySpecialBackground : Boolean = [...]
Column(
    modifier = Modifier
        .fillMaxWidth()
        .conditional(
            applySpecialBackground,
            ifTrue = { background(Color.Red) },
            ifFalse = { background(Color.Blue) }
        )
        .padding(16.dp)

) { [...] }

非常感谢 mtotschnig 指出了之前实现中的一个严重错误!


27
投票
Modifier

有一个

then
函数可以将当前修饰符与另一个修饰符连接起来。此
then
函数返回一个您尚未使用过的新修饰符。您必须使用返回的修饰符重新初始化您的
myModifier
变量。
检查以下代码:

var myModifier = Modifier.padding( start = 4.dp, end = 4.dp, top = 8.dp, bottom = 8.dp ) if (viewWidth == null) myModifier = myModifier.then(Modifier.fillParentMaxWidth(1f)) else myModifier = myModifier.then(Modifier.width(viewWidth)) myModifier = myModifier.then( Modifier .height(viewHeight ?: 100.dp) .clickable(onClick = { listener.onItemClick(item) }) )



17
投票
Modifier.then

val modifier = Modifier
            .padding(start = 4.dp, end = 4.dp, top = 8.dp, bottom = 8.dp)
            .then(if(viewWidth == null) Modifier.fillMaxWidth(1f) else Modifier.width(viewWidth))
            .height(viewHeight ?: 100.dp)
            .clickable(onClick = { listener.onItemClick(item) })

参见:
https://jetc.dev/slack/2020-12-13-conditional-modifiers.html


7
投票

ClickableText( modifier = Modifier .let { if (selectedPosition == index) { return@let it .background( Green200, shape = RoundedCornerShape(12.dp) ) } it } .padding(horizontal = 12.dp, vertical = 4.dp), text = AnnotatedString(categories[index]), style = TextStyle( fontSize = 14.sp, textAlign = TextAlign.Center ), onClick = { selectedPosition = index } )



1
投票

@Composable fun Modifier.conditional(condition: Boolean, modifier: @Composable Modifier.() -> Modifier) = then(if (condition) modifier.invoke(this) else this)



0
投票
https://proandroiddev.com/jetpack-compose-tricks-conditionally-applying-modifiers-for-dynamic-uis-e3fe5a119f45

通用函数

inline fun Modifier.conditional( condition: Boolean, ifTrue: Modifier.() -> Modifier, ): Modifier = conditional(condition = condition, ifTrue = ifTrue, ifFalse = { this }) inline fun Modifier.conditional( condition: Boolean, ifTrue: Modifier.() -> Modifier, ifFalse: Modifier.() -> Modifier, ): Modifier = if (condition) { ifTrue() } else { ifFalse() }

使用方法

val myModifier = Modifier .padding(start = 4.dp, end = 4.dp, top = 8.dp, bottom = 8.dp) .conditional(viewWidth == null, { fillParentMaxWidth(1f) }, { width(viewWidth!!) }) .height(viewHeight ?: 100.dp) .clickable(onClick = { listener.onItemClick(item) })

© www.soinside.com 2019 - 2024. All rights reserved.