聊天界面键盘底部Padding动画

This commit is contained in:
2024-09-24 04:45:55 +08:00
parent b94d8fb7b3
commit c21ef36ecb

View File

@@ -1,10 +1,13 @@
package com.aiosman.riderpro.ui.chat
import android.view.KeyEvent
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -14,6 +17,7 @@ import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
@@ -23,6 +27,8 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
@@ -37,11 +43,19 @@ import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.SoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel
@@ -52,6 +66,7 @@ import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
import com.aiosman.riderpro.ui.composables.StatusBarSpacer
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -146,11 +161,6 @@ fun ChatScreen(userId: String) {
ChatInput() {
viewModel.sendMessage(it, context)
}
Box(
modifier = Modifier
.fillMaxWidth()
.height(navigationBarHeight)
)
}
}
) { paddingValues ->
@@ -320,20 +330,46 @@ fun ChatItem(item: ChatItem, currentUserId: String) {
fun ChatInput(
onSend: (String) -> Unit = {}
) {
val navigationBarHeight = with(LocalDensity.current) {
WindowInsets.navigationBars.getBottom(this).toDp()
}
var keyboardController by remember { mutableStateOf<SoftwareKeyboardController?>(null) }
var isKeyboardOpen by remember { mutableStateOf(false) }
var text by remember { mutableStateOf("") }
val inputBarHeight by animateDpAsState(
targetValue = if (isKeyboardOpen) 8.dp else navigationBarHeight,
animationSpec = tween(durationMillis = 300), label = ""
)
// 在 isKeyboardOpen 变化时立即更新 inputBarHeight 的动画目标值
LaunchedEffect(isKeyboardOpen) {
inputBarHeight // 触发 inputBarHeight 的重组
}
val focusManager = LocalFocusManager.current
val windowInsets = WindowInsets.ime
val density = LocalDensity.current
val softwareKeyboardController = LocalSoftwareKeyboardController.current
val currentDensity by rememberUpdatedState(density)
LaunchedEffect(windowInsets.getBottom(currentDensity)) {
if (windowInsets.getBottom(currentDensity) <= 0) {
focusManager.clearFocus()
}
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp, horizontal = 16.dp)
.padding(horizontal = 16.dp)
.padding(bottom = inputBarHeight)
) {
Box(
modifier = Modifier
.weight(1f)
.clip(androidx.compose.foundation.shape.RoundedCornerShape(16.dp))
.clip(RoundedCornerShape(16.dp))
.background(Color(0xffe5e5e5))
.padding(horizontal = 16.dp),
contentAlignment = androidx.compose.ui.Alignment.CenterStart
) {
BasicTextField(
value = text,
@@ -347,7 +383,23 @@ fun ChatInput(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.onFocusChanged { focusState ->
isKeyboardOpen = focusState.isFocused
}
.pointerInput(Unit) {
awaitPointerEventScope {
keyboardController = softwareKeyboardController
awaitFirstDown().also {
keyboardController?.show()
}
}
},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = {
keyboardController?.hide()
}
)
)
}
Spacer(modifier = Modifier.width(16.dp))