如何处理Jetpack Compose中文本的可见性?

56

我有这段文字:

Text(
    text = stringResource(id = R.string.hello)
)

我该如何显示和隐藏这个组件?

我正在使用Jetpack Compose版本'1.0.0-alpha03'


6
我该如何展示或隐藏这个组件?-- 将该函数调用包装在一个if块中,该块要么调用函数,要么不调用。请记住:Compose是一个函数响应式UI框架。每次需要更改时都会调用您的代码。因此,您的代码将被同时调用以处理“显示”和“隐藏”两种情况,并且您需要在该函数中编写逻辑来处理这两种情况。 - CommonsWare
5个回答

57

正如CommonsWare所说,Compose是一个声明式工具包,它将您的组件与状态(例如:isVisible)绑定在一起,然后Compose将智能地决定哪些组件依赖于该状态并重新组合它们。例如:

@Composable
fun MyText(isVisible: Boolean){
  if(isVisible){
     Text(text = stringResource(id = R.string.hello))
  }
}

你还可以使用AnimatedVisibility() 组合来实现动画效果。


17
这是一个不错的回答。但是,如果我需要一个元素占据其边界但又不可见怎么办呢?我们过去有View.VISIBLE、View.INVISIBLE和View.GONE。使用if语句只需实现GONE和VISIBLE即可。 - Some random IT boy
19
@SomerandomITboy,我可能会将我的if语句放在修饰符内部,类似于Modifier.opacity(if(isVisible) 1f else 0f) - Róbert Nagy
1
我不知道那个修饰符。谢谢! - Some random IT boy
12
尝试在1.0.0-beta04中使用Modifier.alpha(if(isVisible) 1f else 0f)。该代码将根据isVisible的布尔值来设置透明度,如果为真,则设置为完全不透明(1f),否则设置为完全透明(0f)。 - Charles Woodson
1
这是只有在视图可见时才创建文本,对吧?有没有办法先创建视图,然后控制其可见性呢? - David
1
@David,通常情况下你不需要这样做,因为可见性或不可见性是一种“状态”,你可以重新组合它。但在我的情况下,我正在一个约束布局中工作,我不想让锚点消失,只是不想被看到(改变不透明度是一种hack方法)。 - Brill Pappin

45

你可以简单地添加一个条件,如下所示:

  if(isVisible){
     Text("....")
  }

类似于:

var visible by remember { mutableStateOf(true) }
Column() {
    if (visible) {
        Text("Text")
    }
    Button(onClick = { visible = !visible }) { Text("Toggle") }
}

如果您想为内容的出现和消失添加动画效果,可以使用 AnimatedVisibility

var visible by remember { mutableStateOf(true) }
Column() {
    AnimatedVisibility(
        visible = visible,
        enter = fadeIn(
            // Overwrites the initial value of alpha to 0.4f for fade in, 0 by default
            initialAlpha = 0.4f
        ),
        exit = fadeOut(
            // Overwrites the default animation with tween
            animationSpec = tween(durationMillis = 250)
        )
    ) {
        // Content that needs to appear/disappear goes here:
        Text("....")
    }
    Button(onClick = { visible = !visible }) { Text("Toggle") }
}

这就是只有在视图可见时才创建文本,对吧?有没有什么方法可以先创建视图,然后控制其可见性呢? - David

13

如上所述, 您可以使用AnimatedVisibility如下:

AnimatedVisibility(visible = yourCondition) { Text(text = getString(R.string.yourString)) }

4
只有在视图可见时才创建文本?是否有一种方法可以先创建视图,然后控制其可见性? - David

2
/**
 * @param visible if false content is invisible ie. space is still occupied
 */
@Composable
fun Visibility(
    visible: Boolean,
    content: @Composable () -> Unit
) {
    val contentSize = remember { mutableStateOf(IntSize.Zero) }

    Box(modifier = Modifier
        .onSizeChanged { size -> contentSize.value = size }) {
        if (visible || contentSize.value == IntSize.Zero) {
            content()
        } else {
            Spacer(modifier = Modifier.size(contentSize.value.width.pxToDp(), contentSize.value.height.pxToDp()))
        }
    }
}


fun Int.pxToDp(): Dp {
    return (this / getSystem().displayMetrics.density).dp
}

用法:

Visibility(text.value.isNotEmpty()) {
    IconButton(
        onClick = { text.value = "" },
        modifier = Modifier
            .padding(bottom = 8.dp)
            .height(30.dp),
    ) {
        Icon(Icons.Filled.Close, contentDescription = "Clear text")
    }
}

0
这只是使用提出的解决方案之一,创建一个具有记忆值的枚举。
var visible by remember { mutableStateOf(Visibility.VISIBLE) }

这是完整的代码:
enum class Visibility {
    VISIBLE,
    INVISIBLE,
    GONE,
}



  @Composable
fun MyTextWithVisibilityAndOpacity(visibility: Visibility) {
    if (visibility == Visibility.VISIBLE) {
        Text(
            text = "Hello, Jetpack Compose!",
            color = Color.Black,
            fontWeight = FontWeight.Bold,
            modifier = Modifier.padding(16.dp)
                .opacity(if (visibility == Visibility.INVISIBLE) 0f else 1f)
        )
    }
}

@Composable
fun MyApp() {
    var visible by remember { mutableStateOf(Visibility.VISIBLE) }

    Column {
        MyTextWithVisibilityAndOpacity(visible)
        Button(onClick = {
            visible = when (Random.nextInt(3)) {
                0 -> Visibility.VISIBLE
                1 -> Visibility.INVISIBLE
                else -> Visibility.GONE
            }
        }) {
            Text(text = "Toggle Visibility")
        }
    }
}

@Preview
@Composable
fun PreviewApp() {
    MyApp()
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接