Развертывание и свертывание элементов LazyColumn с анимацией в Jetpack Compose.Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Развертывание и свертывание элементов LazyColumn с анимацией в Jetpack Compose.

Сообщение Anonymous »

Я использую StickyHeader с LazyColumn и хочу разворачивать и сворачивать элементы под каждым заголовком при щелчке по заголовку с плавной анимацией. Я реализовал это поведение с помощью AnimatedVisibility, который отлично работает для небольшого количества элементов.
Однако, когда количество элементов под заголовком становится большим (например, 100 + элементы), пользовательский интерфейс начинает значительно отставать во время анимации.
Есть ли лучший способ добиться такого поведения развертывания и свертывания с большей производительностью или есть ли какие-либо оптимизации, которые я могу сделать AnimatedVisibility?
Любые советы и альтернативные подходы приветствуются!
Текущая реализация:

Код: Выделить всё

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun AnimatedImageWithTextItem(groupedItems: Map) {
val state = remember { mutableStateMapOf() }
LazyColumn(
modifier = Modifier
.fillMaxSize().
) {

groupedItems.onEachIndexed { groupIndex, (key, elements) ->
val isExpanded = state[key] ?: true
stickyHeader {
Row(modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.background(Color.Yellow)
.clickable { state[key] = !isExpanded })
{
Text("header $key")
}
}

itemsIndexed(
items = elements,
key = { _, item -> item.id }) { elementIndex, element ->

ExpandableContent(isExpanded) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.background(Color.White))
{
Text("Item of the header")
}

}
}

}
}
}

const val EXPANSTION_TRANSITION_DURATION = 300
@Composable
fun ExpandableContent(
visible: Boolean = true,
content: @Composable () -> Unit
) {
val enterTransition = remember {
expandVertically(
expandFrom = Alignment.Top,
animationSpec = tween(EXPANSTION_TRANSITION_DURATION)
) + fadeIn(
initialAlpha = 0.3f,
animationSpec = tween(EXPANSTION_TRANSITION_DURATION)
)
}
val exitTransition = remember {
shrinkVertically(
// Expand from the top.
shrinkTowards = Alignment.Top,
animationSpec = tween(EXPANSTION_TRANSITION_DURATION)
) + fadeOut(
// Fade in with the initial alpha of 0.3f.
animationSpec = tween(EXPANSTION_TRANSITION_DURATION)
)
}

AnimatedVisibility(
visible = visible,
enter = enterTransition,
exit = exitTransition
) {
content()
}
}
Класс документа:

Код: Выделить всё

data class Document(
val title: String?,
val date: String,
val text: String?,
val id: Int,
)
Вот как я создаю фиктивный список данных:

Код: Выделить всё

fun generateDummyDocuments(numberOfDocuments: Int): List {
val documents = mutableListOf()
for (i in 1..numberOfDocuments) {
val title = "Document Title $i"
val date = "2024-09-01"
val text = "This is the content of document $i.  It's a dummy text."
val id = i

val document = Document(title, date, text, id)
documents.add(document)
}
return documents
}
Вот класс активности:

Код: Выделить всё

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

setContent {
ComposetestTheme {
var documents by remember {
mutableStateOf(
emptyMap()
)
}

LaunchedEffect(Unit) {
documents = generateDummyDocuments(100).groupBy { it.date }

}

AnimatedImageWithTextItem(documents)
}
}
}
}
Изображение


Подробнее здесь: https://stackoverflow.com/questions/790 ... ck-compose
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»