所以我正在尝试制作一个短信应用程序作为一个学习项目。我从 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"
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 示例应用程序。它提供了聊天应用程序的演示实现,可能会对您有所帮助。