如何使用键盘向上移动惰性列内容?撰写

问题描述 投票:0回答:1

所以我正在尝试制作一个短信应用程序作为一个学习项目。我从 firebase 上传了短信并将其加载到惰性列中,我还有一个用于发送和输入消息的文本字段,我将它们分解为几个不同的可组合项 这是他懒惰专栏所在的地方

Composable
fun TextSectionAndKeyBoard(
    state:LazyListState,
    messageList:List<MessageModel>,
    currentUserSenderId:String,
    match:MatchedUserModel = MatchedUserModel(),
    message:String,
    sendMessage: () -> Unit,
    sendAttachment: () -> Unit,
    messageChange: (String) -> Unit,
    feedBack:Boolean = false
){
    Column(
        Modifier.fillMaxSize()
    ) {
        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .statusBarsPadding()
                .weight(1f)
                .imePadding(),
            state = state
        ) {
            itemsIndexed(messageList) { index, message ->
                val last = index == (messageList.size -1)
                val isCurrentUser = message.senderId.contains(currentUserSenderId.replaceFirstChar { "" })
                val time = message.currentTime
                if(feedBack){
                    MessageItemFeedBack(message = message, isCurrentUser = isCurrentUser, timeStamp = time, last)
                }else{
                    MessageItem(match = match ,message = message, isCurrentUser = isCurrentUser, timeStamp = time, last)
                }
            }
            item(key = "keyboard"){

            }
            item{
                Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
                Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
            }
        }
        MessagingBar(
            modifier = Modifier.weight(1f),
            message = message,
            messageChange = messageChange,
            sendMessage = sendMessage,
            sendAttachment = sendAttachment
        )
    }
}

正如你所看到的,我有一个带有 id 键盘的项目,我最初在那里有键盘,当它在那里时,当我打开键盘时,我能够影响惰性列,在需要时将所有项目向上移动。但键盘也是底部的项目,所以你始终看不到键盘部分,这并不理想

@Composable
fun MessagingBar(
    modifier: Modifier,
    message:String,
    messageChange: (String) -> Unit,
    sendMessage: () -> Unit,
    sendAttachment: () -> Unit
){
    Row(modifier = Modifier
        .background(AppTheme.colorScheme.onTertiary)
        .fillMaxWidth()
        .padding(12.dp)){
        Row (
            modifier = Modifier.fillMaxWidth(),
            //horizontalArrangement = Arrangement.SpaceEvenly
        ){
            IconButton(onClick = sendAttachment,
                modifier = Modifier
                    .offset(y = 5.dp)
                    .weight(1.0F),
                colors= IconButtonDefaults.iconButtonColors(
                    containerColor = Color.Transparent,
                    contentColor = AppTheme.colorScheme.secondary,
                ),
            ) {
                Icon(imageVector = ImageVector.vectorResource(id = R.drawable.attachment), contentDescription = "Send")
            }
            OutlinedTextField(
                modifier = Modifier
                    .fillMaxWidth()
                    .weight(7.5F),
                value = message, onValueChange = messageChange,
                textStyle = baseAppTextTheme(),
                keyboardOptions = KeyboardOptions(
                    keyboardType = KeyboardType.Text,
                    capitalization = KeyboardCapitalization.Sentences,
                    autoCorrect = true,
                ),
                maxLines = 4,

                )
            IconButton(onClick = sendMessage,
                modifier = Modifier
                    .offset(y = 5.dp)
                    .weight(1.0F),
                colors= IconButtonDefaults.iconButtonColors(
                    containerColor = Color.Transparent,
                    contentColor = AppTheme.colorScheme.secondary,
                ),
            ) {
                Icon(imageVector = ImageVector.vectorResource(id = R.drawable.send), contentDescription = "Send")
            }
        }
    }
}

这是键盘,简单的行,带有用于发送消息和附件的按钮以及概述的文本字段

@Composable
fun MessagerScreen(navController: NavHostController, vm: ViewModel){
    val talkedUser by vm.selectedUser.collectAsState()
    val avail by remember {mutableStateOf(talkedUser == null)}
    if(avail && talkedUser == null){
        InsideMessages(
            nav = navController,
            titleText = "Loading",
            chatSettings = {},
            messages = {}
        )
    }else{
        val chatId = vm.getChatId(vm.getUser().number, talkedUser!!.number) //change to UID later need to account for reverses
        var message by rememberSaveable { mutableStateOf("") }
        val messageModel = viewModel { MessageViewModel(MyApp.x) }
        val messageList by messageModel.getChatData(chatId).collectAsState(listOf())
        //TODO need to make this work
        var scrollValue by remember { mutableIntStateOf(messageList.size) }
        val state = rememberLazyListState()
        LaunchedEffect(scrollValue) {
            state.scrollToItem(scrollValue+1)
        }
        InsideMessages(
            nav = navController,
            titleText = talkedUser!!.name,
            goToProfile = { navController.navigate("MatchedUserProfile") },
            chatSettings = {},
            startCall = {/* TODO Start normal Call (Need to make a screen for it)*/},
            startVideoCall = {/* TODO Start Video Call (Need to make a screen for it)*/},
            messages = {
                TextSectionAndKeyBoard(
                    state = state,
                    messageList = messageList,
                    currentUserSenderId = messageModel.getCurrentUserSenderId(),
                    match = talkedUser!!,
                    message = message,
                    messageChange = { message = it },
                    sendMessage = {
                        if (message != "") {
                            messageModel.storeChatData(chatId, message)
                        }
                        message = ""
                        scrollValue = messageList.size + 2
                    },
                    sendAttachment = {/* TODO photos or attachments Message...advise if we should keep*/ }
                )
            },
        )
    }
}

这是它保存在屏幕上的位置,这里没有什么非常重要的,它有 LazyListState,当您发送新消息时更新,确保它保持在底部。

我需要帮助来弄清楚我需要对我的惰性列做什么,它可以识别键盘并将最后一个项目保留在 MessagingBar() 上方,以便您可以正确阅读最后一条消息

我的清单中有 android:windowSoftInputMode="adjustResize"

kotlin android-jetpack-compose lazycolumn
1个回答
0
投票

查看

imePadding
修改器的文档。当键盘打开时,它会自动将必要的填充应用于可组合项。

您可以将其应用到您的

MessagingBar
可组合项,如下所示:

MessagingBar(
    modifier = Modifier.imePadding(),
    message = message,
    messageChange = messageChange,
    sendMessage = sendMessage,
    sendAttachment = sendAttachment
)

确保在

MessagingBar
可组合项中实际应用传递的修饰符,您当前没有执行的操作:

@Composable
fun MessagingBar(
    modifier: Modifier,
    message:String,
    messageChange: (String) -> Unit,
    sendMessage: () -> Unit,
    sendAttachment: () -> Unit
){
    Row(modifier = modifier  // APPLY PASSED MODIFIER HERE
        .background(AppTheme.colorScheme.onTertiary)
        .fillMaxWidth()
        .padding(12.dp)) {
        //...
    }
}

请注意,您不应在

weight
上设置
MessagingBar
修饰符,那里不需要它。


另请查看官方 JetChat 示例应用程序。它提供了聊天应用程序的演示实现,可能会对您有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.