在 LazyColumn 中将单个 AnimatedVisibility 设置为 true

Posted

技术标签:

【中文标题】在 LazyColumn 中将单个 AnimatedVisibility 设置为 true【英文标题】:Set a single AnimatedVisibility to true in a LazyColumn 【发布时间】:2022-01-01 21:00:32 【问题描述】:

我有一个用于操作系统信息的可组合功能,它在单击时展开详细信息并在再次单击时恢复。

@ExperimentalAnimationApi
@Composable
fun OSCard(os: OS) 
    var expanded by remember 
        mutableStateOf(false)
    
    Column(modifier = Modifier
        .clickable  expanded = !expanded 
        .fillMaxWidth()) 
        Text(
            modifier = Modifier
                .padding(20.dp),
            text = os.name,
            style = MaterialTheme.typography.h6
        )
        AnimatedVisibility(visible = expanded) 
            Text(text = os.description, modifier = Modifier.padding(20.dp))
        
        Divider(Modifier.height(2.dp))
    

我创建了一个列表并通过LazyColumn 传递它

var OSs = listOf<OS>(
    OS(
        "android",
        "Android is a mobile/desktop operating system..."
      ),
    OS(
        "Microsoft Windows",
        "Microsoft Windows, commonly referred to as Windows..."
      ),
    OS(
        "Linux",
        "Linux is a family of open-source Unix-like operating systems..."
      )
)

Surface(color = MaterialTheme.colors.background) 
    LazyColumn(modifier = Modifier.fillMaxSize()) 
        items(items =  OSs)
            os -> OSCard(os)
        
    

虽然它按预期工作,但我想让它这样,如果打开一张卡并选择另一张卡,之前打开的卡将被关闭。

这是我想要避免的,有人可以给我一些提示吗?

【问题讨论】:

【参考方案1】:

这是一种解决方案。向您的操作系统对象添加一个名为isExpanded 的参数。只有当您单击卡片时,它才会设置为 true。点击处理程序将清除所有其他卡片中的标志。

我还添加了一个id 参数,可以更轻松地找到被点击的项目。可以使用name 参数。

需要读取状态变量expandCard 以触发重组,因此使用var e = expandCard 读取值。另请注意,您的列表的创建必须在可组合之外,否则最终只会重新创建,并且所有项目的 isExpanded 字段都将设置为 false。

最后,我不确定您为什么要为此使用 LazyColumn。 LazyColumn 真正适用于大型数据集,主要用于分页。如果您有合理数量的项目,您可以只使用带有垂直滚动的普通 Column。

class MainActivity : ComponentActivity() 
    @ExperimentalAnimationApi
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)

        var OSs = listOf(
            OS(
                id = "android",
                name = "Android",
                description =  "Android is a mobile/desktop operating system..."
            ),
            OS(
                id = "mswindows",
                name = "Microsoft Windows",
                description = "Microsoft Windows, commonly referred to as Windows..."
            ),
            OS(
                id = "linux",
                name ="Linux",
                description = "Linux is a family of open-source Unix-like operating systems..."
            )
        )

        setContent 

            var expandCard by remember  mutableStateOf(false) 
            var e = expandCard

            Surface() 
                LazyColumn(  modifier = Modifier.fillMaxSize()) 
                    itemsIndexed(
                        items = OSs,
                        key =  index, os ->
                            os.name
                        
                    )  index, os ->
                        OSCard(os) osClicked ->
                            val isExpanded = osClicked.isExpanded
                            OSs.forEach  it.isExpanded = false 
                            OSs.first  it.id == osClicked.id .isExpanded = isExpanded
                            expandCard = !expandCard
                        
                    
                
            
        
    


@ExperimentalAnimationApi
@Composable
fun OSCard(
    os: OS,
    onClick: (os: OS) -> Unit
) 

    Column(modifier = Modifier
        .clickable 
            os.isExpanded = !os.isExpanded
            onClick(os)
        
        .fillMaxWidth()) 
        Text(
            modifier = Modifier
                .padding(20.dp),
            text = os.name,
            style = MaterialTheme.typography.h6
        )

        AnimatedVisibility(visible = os.isExpanded) 
            Text(text = os.description, modifier = Modifier.padding(20.dp))
        
        Divider(Modifier.height(2.dp))
    


class OS(var id: String, var name: String, var description: String, var isExpanded: Boolean= false)

【讨论】:

我很高兴得到答案以及对做什么和不做什么的解释。我很欣赏分享的知识。谢谢。

以上是关于在 LazyColumn 中将单个 AnimatedVisibility 设置为 true的主要内容,如果未能解决你的问题,请参考以下文章

使用权重修饰符在 LazyColumn 中排列单个项目

LazyColumn 中每个项目的状态提升

如何在 Adob​​e Animate CC 2019 中将主时间线影片剪辑与 html5 画布混合

在单个元素上使用多个动画(连续)

LazyColumn 比垂直滚动的 Column 慢

带有 SwipeToDismiss 的 LazyColumn