Отображение ленивого списка с разбивкой на страницы внутри открытого раскрывающегося спискаAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Гость
 Отображение ленивого списка с разбивкой на страницы внутри открытого раскрывающегося списка

Сообщение Гость »

В нашем приложении нам нужно отображать постраничный список опций внутри раскрывающегося меню. Поскольку список данных является ленивым, его размер не является постоянным и, следовательно, может вызвать сбои, если вложенному составному элементу PaginatedLazyColumn() не присвоены значения постоянного размера. Очевидно, это выглядит плохо, поэтому мой вопрос: как мне к этому подойти?
Должен ли я каким-то образом вычислить ширину самой длинной строки данных (которая доступна на странице 0 полезных данных, поскольку, если появляется более длинная строка, ее можно обрезать) и установить ее как ширину раскрывающегося списка, сохраняя при этом высоту «комфортного» размера DP? Если да, то как я могу это сделать?
Я создал следующий составной объект, который представляет собой раскрывающийся список в нашем приложении:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LyraDropDown(
modifier: Modifier = Modifier,
data: List,
defaultSelectionIndex: Int = 0,
label: String,
onClick: (Int) -> Unit,
paginationCallback: () -> Unit = {},
itemContent: @Composable (String) -> Unit
) {
var expanded by remember { mutableStateOf(false) }
var selectedIndex by remember { mutableIntStateOf(defaultSelectionIndex) }
val listWithDefaultOption = data.toMutableList()
listWithDefaultOption.add(0, "No selection")

ExposedDropdownMenuBox(
modifier = modifier.background(
colorResource(id = R.color.white),
shape = RoundedCornerShape(8.dp)
),
expanded = expanded, onExpandedChange = { expanded = !expanded }) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.menuAnchor()
.background(colorResource(id = R.color.white), shape = RoundedCornerShape(8.dp)),
readOnly = true,
label = {
Text(label, fontSize = 12.sp)
},
value = listWithDefaultOption[selectedIndex],
textStyle = TextStyle(fontSize = 12.sp),
onValueChange = { },
trailingIcon = {
Icon(
painter = painterResource(id = if (!expanded) R.drawable.ic_chev_down else R.drawable.ic_chev_up),
contentDescription = null,
modifier = Modifier
.size(24.dp)
.padding(4.dp),
tint = colorResource(id = R.color.gray_700)
)
},
shape = RoundedCornerShape(8.dp),
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(
unfocusedContainerColor = colorResource(id = R.color.white),
focusedContainerColor = colorResource(id = R.color.white),
focusedBorderColor = colorResource(id = R.color.indigo_500),
unfocusedBorderColor = colorResource(id = R.color.gray_200),
focusedLabelColor = colorResource(id = R.color.blue_500),
unfocusedLabelColor = colorResource(id = R.color.black)
)
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
},
modifier = Modifier
.background(colorResource(id = R.color.white))
.width(200.dp)
.height(300.dp),
) {

PaginatedLazyColumn(
modifier = Modifier
.width(200.dp)
.height(300.dp),
items = listWithDefaultOption,
itemKey = { UUID.randomUUID() },
itemContentIndexed = { selectionOption, index ->
DropdownMenuItem(
onClick = {
selectedIndex = index
expanded = false
if (index != 0) onClick(index - 1) // account for hardcoded option
},
text = {
itemContent(selectionOption)
})
},
loadingItem = { LyraCircularProgressIndicator() },
contentWhenEmpty = { }) {
paginationCallback()
}
}
}
}

PaginatedLazyColumn определяется как:
@Composable
internal fun PaginatedLazyColumn(
modifier: Modifier = Modifier,
loading: Boolean = false,
listState: LazyListState = rememberLazyListState(),
items: List,
itemKey: (T) -> Any,
itemContentIndexed: @Composable (T, Int) -> Unit,
loadingItem: @Composable () -> Unit,
contentWhenEmpty: @Composable () -> Unit,
loadMore: () -> Unit
) {

val reachedBottom: Boolean by remember { derivedStateOf { listState.reachedBottom() } }

// load more if scrolled to bottom
LaunchedEffect(reachedBottom) {
if (reachedBottom && !loading) loadMore()
}

LazyColumn(modifier = modifier, state = listState) {
itemsIndexed(
items = items,
key = { _, item -> itemKey(item) }
) { index, item ->
itemContentIndexed(item, index)
}
if (items.isEmpty()) {
item {
contentWhenEmpty()
}
}
if (loading) {
item {
loadingItem()
}
}
}
}

private fun LazyListState.reachedBottom(buffer: Int = 1): Boolean {
val lastVisibleItem = this.layoutInfo.visibleItemsInfo.lastOrNull()
return lastVisibleItem?.index != 0 && lastVisibleItem?.index == this.layoutInfo.totalItemsCount - buffer
}


Подробнее здесь: https://stackoverflow.com/questions/781 ... eddropdown
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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