在 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的主要内容,如果未能解决你的问题,请参考以下文章