【发布时间】:2023-01-18 02:01:13
【问题描述】:
我试图找出一种方法来维护跨重组的排序列表。根据我的阅读,排序应该在 viewModel 中完成,但我的用例似乎不适合。我在我的DataTable 组件中显示一个列表。该列表最初是未排序的,但当用户单击 TableHeader 时将对其进行排序。 DataTable 用于我的 DataTableView 屏幕,它有许多状态变量,导致整个可组合项 (DataTableView) 被重新组合,因此显示原始未排序的列表。在重新组合时维护排序列表的最佳方法是什么,或者是分离可组合项但将它们放在同一屏幕上的解决方案?
数据表可组合
fun DataTable(
modifier: Modifier,
list: List<Person>
) {
// list comes from viewModel, example of data that is being passed
val list = mutableStateOf(listOf(Person("Adam", 20), Person("James", 32), Person("Ryan", 21)))
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(all = 16.dp),
verticalArrangement = Arrangement.spacedBy(space = 16.dp)
) {
items(
items = list
) {
TableHeader(modifier = Modifier.clickable {
list.value = list.value.sortedBy { it.name }
}
}
}
表头可组合
fun RowScope.TableHeader(
modifier: Modifier = Modifier,
text: String,
sortIcon: @Composable (() -> Unit?)? = null
) {
Row(
modifier = modifier
.border(.4.dp, Color.Black)
.weight(weight)
.padding(4.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = text,
color = MaterialTheme.colors.onPrimary
)
sortIcon?.let { sortIcon ->
sortIcon()
}
}
}
DataTableView 可组合
fun DataTableView(viewModel: ViewModel = viewModel()) {
var inputText: TextFieldValue by remember { mutableStateOf(TextFieldValue("")) }
val drawerState = rememberBottomDrawerState(initialValue = BottomDrawerValue.Closed)
DrawerBottom(
gesturesEnabled = drawerState.isOpen,
drawerState = drawerState,
drawerContent = {}
) {
Scaffold(
topBar = { AppBar() },
floatingActionButton = {
FloatingActionButton(
onClick = { coroutineScope.launch { drawerState.open() } },
modifier = Modifier
.width(36.dp)
.height(36.dp),
imageVector = Icons.Filled.KeyboardArrowUp
)
},
floatingActionButtonPosition = FabPosition.End,
isFloatingActionButtonDocked = true,
) {
Column {
TextField(
value = inputText.text,
onValueChange = { newText ->
inputText = newText
},
)
DataTable(
list = viewModel.personList
)
}
}
}
}
DrawerBottom 可组合
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun DrawerBottom(
modifier: Modifier = Modifier,
drawerState: BottomDrawerState,
drawerContent: @Composable ColumnScope.() -> Unit,
drawerElevation: Dp = DrawerDefaults.Elevation,
drawerShape: Shape = RectangleShape,
gesturesEnabled: Boolean = false,
drawerBackgroundColor: Color = MaterialTheme.colors.background,
content: @Composable () -> Unit
) {
BottomDrawer(
modifier = modifier,
drawerState = drawerState,
drawerContent = drawerContent,
drawerElevation = drawerElevation,
drawerShape = drawerShape,
gesturesEnabled = gesturesEnabled,
drawerBackgroundColor = drawerBackgroundColor,
content = content
)
}
我已经尝试在 viewModel 中对列表进行排序,但是当 DataTableView 重新组合时,但这意味着我需要将 viewModel 传递到我的 DataTable 可组合项中,并且根据我的理解,您希望保持 viewModels 高级别,例如,屏幕级别。
【问题讨论】:
-
“我已经尝试在 viewModel 中对列表进行排序,但是当 DataTableView 重新组合时,它仍将与传入的原始列表组合。”这就是我要推荐的内容——你知道为什么传入的是原始列表吗——原始列表不应该是
list = viewModel.personList,它仍然会被排序吗?也可以试试val list = remember { mutableStateListOf<Person>()}或val list = remember { viewModel.personLIst }之类的东西 -
@ryankuck 我错了,列表已排序,但要使用该函数对列表进行排序,我必须将 viewModel 传递到我的 DataTable 可组合项中,根据我的理解,您希望保持 viewModel 高级(屏幕级别) ), 正确的?我编辑了我的帖子以反映此评论。
标签: sorting android-jetpack-compose android-viewmodel compose-recomposition