В нашем приложении нам нужно отображать постраничный список опций внутри раскрывающегося меню. Поскольку список данных является ленивым, его размер не является постоянным и, следовательно, может вызвать сбои, если вложенному составному элементу 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
Отображение ленивого списка с разбивкой на страницы внутри открытого раскрывающегося списка ⇐ Android
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Создайте список URL-адресов с разбивкой на страницы из списка результатов.
Anonymous » » в форуме C# - 0 Ответы
- 13 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Можно ли использовать кнопки при сохранении раскрывающегося списка открытого Combobox?
Anonymous » » в форуме C# - 0 Ответы
- 42 Просмотры
-
Последнее сообщение Anonymous
-