当前位置: 首页 > 知识库问答 >
问题:

初始值必须有关联的锚点ModalBottomSheetLayout

高寒
2023-03-14

我创建了一个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或谷歌上找不到太多东西。

共有1个答案

车明贤
2023-03-14

我完全错过了可选参数< 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。将代码更改为此: 此外,我会将所有这些整合到一个初始化器中。