在 LazyColumn 中将单个 AnimatedVisibility 设置为 true
Set a single AnimatedVisibility to true in a LazyColumn
我有一个用于操作系统信息的可组合函数,它会在单击时扩展详细信息,并在再次单击时还原。
@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)
}
}
}
虽然它按预期工作,但我想让它在打开一张卡并选择另一张卡时关闭之前打开的卡。
这是我想要避免的,有人可以告诉我如何做吗?
这是一种解决方案。向名为 isExpanded
的 OS 对象添加一个参数。只有当您单击卡片时,它才会设置为 true。单击处理程序将清除所有其他卡片中的标志。
我还添加了一个 id
参数,这样可以更轻松地找到被单击的项目。可以使用 name
参数。
状态变量 expandCard
需要读取才能触发重组,因此 var e = expandCard
用于读取值。另请注意,您的列表的创建必须在可组合项之外,否则它最终会被重新创建并且所有项目的 isExpanded 字段都将设置为 false。
最后,我不确定您为什么为此使用 LazyColumn。 LazyColumn 真正适用于大型数据集,主要用于分页。如果您有合理数量的项目,您可以只使用垂直滚动的普通列。
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)
我有一个用于操作系统信息的可组合函数,它会在单击时扩展详细信息,并在再次单击时还原。
@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)
}
}
}
虽然它按预期工作,但我想让它在打开一张卡并选择另一张卡时关闭之前打开的卡。
这是我想要避免的,有人可以告诉我如何做吗?
这是一种解决方案。向名为 isExpanded
的 OS 对象添加一个参数。只有当您单击卡片时,它才会设置为 true。单击处理程序将清除所有其他卡片中的标志。
我还添加了一个 id
参数,这样可以更轻松地找到被单击的项目。可以使用 name
参数。
状态变量 expandCard
需要读取才能触发重组,因此 var e = expandCard
用于读取值。另请注意,您的列表的创建必须在可组合项之外,否则它最终会被重新创建并且所有项目的 isExpanded 字段都将设置为 false。
最后,我不确定您为什么为此使用 LazyColumn。 LazyColumn 真正适用于大型数据集,主要用于分页。如果您有合理数量的项目,您可以只使用垂直滚动的普通列。
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)