我创建了一个ModalBottomSheetLayout composable,它通过两种实现动态获取其内容:第一种实现在一次晶圆厂点击时打开底部工作表:
@OptIn(ExperimentalMaterialApi::class)
private fun setupFabClickListener(arrayRolesResponse: Set<String>?) {
binding.btnAdd.setOnClickListener {
val arrayString = arrayLocalDate.map { item -> item.toString() }
arrayString as ArrayList<String>
if (arrayRolesResponse != null && "admin" in arrayRolesResponse) {
mainViewModel.toggleBottomSheet()
} else {
getCalendarActivityIntent(this, true)
}
}
}
private var _openBottomSheet =
MutableLiveData(ModalBottomSheetState(ModalBottomSheetValue.Hidden))
val openBottomSheet: LiveData<ModalBottomSheetState> = _openBottomSheet
fun toggleBottomSheet() {
_openBottomSheet.postValue(
if (_openBottomSheet.value?.currentValue == ModalBottomSheetValue.Hidden) {
ModalBottomSheetState(initialValue = ModalBottomSheetValue.Expanded)
} else {
ModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
}
)
}
它按预期工作,而第二个,像这样实现,抛出一个IllegalArgumentException
,其中初始值必须有一个关联的锚。
@OptIn(ExperimentalMaterialApi::class)
private fun setupCompose(date: String) {
binding.composeView.setContent {
val isLoading by viewModel.isLoaded.observeAsState()
val reservations by viewModel.reservationsInDates.observeAsState()
val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val coroutineScope = rememberCoroutineScope()
ReservationsListPage(
reservationsList = reservations?.data?.content,
isLoading = isLoading,
date = date,
bottomSheetState = modalBottomSheetState
) { coroutineScope.launch { modalBottomSheetState.show() } }
}
}
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun ReservationsListPage(
reservationsList: List<Content>?,
isLoading: Boolean?,
date: String,
bottomSheetState: ModalBottomSheetState,
onBottomSheetCall: () -> Unit
) {
Column {
AppBar(onBottomSheetCall)
if (isLoading == true) {
LoadingSpinner()
} else {
ReservationsListHeading(
month = getAbbreviatedMonth(date.getMonth()),
dayOfWeek = formatDayOfWeek(date.getDayOfWeek()),
numberOfMonth = date.getDayOfMonth()
)
ReservationsList(reservationsList)
BottomSheet(state = bottomSheetState) {
ListItem() {
Text(text = "Show / Hide rejected reservations")
}
}
}
}
}
@Composable
fun ReservationsList(reservationsList: List<Content>?) {
Column(
modifier = Modifier.padding(16.dp)
) {
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
reservationsList?.forEach {
item { ReservationsListItem(it) }
}
}
}
}
@Composable
fun ReservationsListItem(reservation: Content) {
val pending = painterResource(R.drawable.ic_pending)
val accepted = painterResource(R.drawable.ic_accepted)
val rejected = painterResource(R.drawable.ic_rejected)
Card(
shape = MaterialTheme.shapes.small,
backgroundColor = lightWhite,
modifier = Modifier.padding(top = 8.dp, bottom = 8.dp),
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp, bottom = 8.dp, start = 16.dp, end = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Column(Modifier.weight(2f)) {
Text(
text = "${reservation.seat?.room?.description}",
style = MaterialTheme.typography.h6
)
Text(
text = "${reservation.user?.username}",
style = MaterialTheme.typography.subtitle1
)
}
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = "${reservation.seat?.description}",
style = MaterialTheme.typography.subtitle1,
)
Icon(
painter = when (reservation.reservationStatus?.status) {
"ACCEPTED" -> accepted
"REJECTED" -> rejected
else -> pending
},
contentDescription = "Reservation status",
tint = Color.Unspecified,
)
}
}
}
}
@Composable
fun AppBar(onBottomSheetCall: () -> Unit) {
var isMenuExpanded by remember { mutableStateOf(false) }
Column() {
TopAppBar(
title = { Text(text = "Reservations", color = Color.White) },
actions = {
IconButton(onClick = { isMenuExpanded = true }) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "More options",
tint = Color.White
)
}
AppBarDropdownMenu(
isMenuExpanded = isMenuExpanded,
onBottomSheetCall = onBottomSheetCall,
onDismissRequest = { isMenuExpanded = false }
)
},
backgroundColor = primary,
)
}
}
@Composable
@OptIn(ExperimentalMaterialApi::class)
fun AppBarDropdownMenu(
isMenuExpanded: Boolean,
onDismissRequest: () -> Unit,
onBottomSheetCall: () -> Unit
) {
DropdownMenu(expanded = isMenuExpanded, onDismissRequest = onDismissRequest) {
DropdownMenuItem(onClick = { /*TODO*/ }) {
ListItem(
icon = { Icon(painterResource(R.drawable.ic_sort), "Sort") }
) { Text(text = "Sort", style = MaterialTheme.typography.body1) }
}
Divider()
DropdownMenuItem(onClick = onBottomSheetCall) {
ListItem(
icon = { Icon(painterResource(R.drawable.ic_filter), "Filter") }
) { Text(text = "Filter", style = MaterialTheme.typography.body1) }
}
}
}
@Composable
fun ReservationsListHeading(month: String, dayOfWeek: String, numberOfMonth: String) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp, start = 16.dp, end = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
HeadingLeft(month = month, dayOfWeek = dayOfWeek, numberOfMonth = numberOfMonth)
}
}
@Composable
fun HeadingLeft(month: String, dayOfWeek: String, numberOfMonth: String) {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Text(text = month, style = MaterialTheme.typography.h3)
Column(
modifier = Modifier.padding(8.dp)
) {
Text(text = dayOfWeek, style = MaterialTheme.typography.body1)
Text(text = numberOfMonth, style = MaterialTheme.typography.subtitle1)
}
}
}
这是我对ModalBottomSheetLayout的实现。
@Composable
@OptIn(ExperimentalMaterialApi::class)
fun BottomSheet(
state: ModalBottomSheetState,
content: @Composable () -> Unit
) {
ModalBottomSheetLayout(
sheetContent = {
Column(
Modifier
.fillMaxWidth()
.padding(top = 8.dp, bottom = 8.dp)
) {
content()
}
},
sheetElevation = 0.dp,
sheetState = state,
) {}
}
知道为什么会发生这种情况吗?我在SO或谷歌上找不到太多东西。
我完全错过了可选参数< code >内容:(@Composable () -
kotlin prettyprint-override">fun ReservationsListPage(
reservationsList: ArrayList<Content>,
isLoading: Boolean?,
date: String,
bottomSheetState: ModalBottomSheetState,
) {
Column {
BottomSheet(
pageContent = {
Column {
AppBar(bottomSheetState)
if (isLoading == true) {
LoadingSpinner()
} else {
ReservationsListHeading(
month = getAbbreviatedMonth(date.getMonth()),
dayOfWeek = formatDayOfWeek(date.getDayOfWeek()),
numberOfMonth = date.getDayOfMonth()
)
ReservationsList(reservationsList)
}
}
},
content = {
Column {
Text("Hello")
}
},
state = bottomSheetState,
)
}
}
问题内容: 为什么Kotlin对此抱怨: 编译器抱怨在Line中由处理程序再次发布。这在纯Java中确实有效: 问题答案: Kotlin认为一个属性在其初始化程序结束之前尚未初始化,因此即使在lambda中也无法在其自己的初始化程序中使用该属性。这种语义类似于其初始化程序内部局部变量使用的限制。 有几种解决方法: 使用对象表达式可以引用已声明的对象: } 这仅适用于接口作为lambda的替代品,并
这肯定是个愚蠢的问题,但我对Kotlin真的是个新手,我没有找到任何解决办法。 如何声明类字段?就像我们可以在Java中拥有它一样: 在中: 但我得到一个警告:“属性必须初始化或抽象”
我有一个编辑文本。我希望这个编辑文本始终保持焦点和可写性。我怎么能每次都不碰它呢?因为条形码扫描器机器将数据连续发送到此应用程序。 我尝试了很多方法。但它们都不起作用。我可以设置键盘是可见的,但光标不在编辑文本上。
问题内容: 据报道,这段代码在这里和这里都有效,但是我似乎无法使其正常工作。 IBOutlet已连接到情节提要中的对象。命名了prototypeCell,因此我可以将其使用,并将其自定义类属性设置为。 First Error(我可以解决,但上面的链接都不需要它,这使我觉得我做错了。对吗?): 第二个错误(有趣的错误): 单元类别代码: 初始化代码: 问题答案: 第一个初始化程序的正确签名是: 请注
问题内容: 这段代码适用于第一个XCode 6 Beta,但在最新的Beta中,它不起作用,并显示以下错误 : 这就是此类的初始化方式: 我坚持下去..最简单的解决方法是什么? 问题答案: 是SKSpriteNode类中唯一指定的初始值设定项,其余都是方便的初始值设定项,因此您不能在它们上调用super。将代码更改为此: 此外,我会将所有这些整合到一个初始化器中。