keyboard jumpy fix
This commit is contained in:
@@ -19,7 +19,8 @@
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop">
|
||||
android:launchMode="singleTop"
|
||||
android:windowSoftInputMode="adjustNothing">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
@@ -44,6 +45,8 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Path
|
||||
@@ -289,7 +292,8 @@ fun MessageTimeline(
|
||||
.padding(
|
||||
top = contentPadding.calculateTopPadding(),
|
||||
bottom = contentPadding.calculateBottomPadding(),
|
||||
),
|
||||
)
|
||||
.imePadding(),
|
||||
) {
|
||||
if (selectedChannel != null) {
|
||||
if (selectedThread != null) {
|
||||
@@ -1372,18 +1376,78 @@ private fun MessageInput(
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
TextField(
|
||||
value = text,
|
||||
onValueChange = { text = it },
|
||||
placeholder = { Text("Message #$channelName", color = MaterialTheme.colorScheme.onSurfaceVariant) },
|
||||
modifier = Modifier.weight(1f).clip(RoundedCornerShape(8.dp)).heightIn(max = 160.dp),
|
||||
maxLines = 8,
|
||||
colors = TextFieldDefaults.colors(
|
||||
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
unfocusedIndicatorColor = Color.Transparent,
|
||||
focusedIndicatorColor = Color.Transparent,
|
||||
),
|
||||
val surfaceVariant = MaterialTheme.colorScheme.surfaceVariant
|
||||
val onSurface = MaterialTheme.colorScheme.onSurface
|
||||
val onSurfaceVariant = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
val textStyle = MaterialTheme.typography.bodyLarge
|
||||
val density = LocalDensity.current
|
||||
AndroidView(
|
||||
factory = { ctx ->
|
||||
object : android.widget.EditText(ctx) {
|
||||
override fun requestRectangleOnScreen(rect: android.graphics.Rect?, immediate: Boolean): Boolean {
|
||||
// Disable system scroll-into-view; Compose imePadding() handles it
|
||||
return false
|
||||
}
|
||||
}.apply {
|
||||
hint = "Message #$channelName"
|
||||
setHintTextColor(onSurfaceVariant.toArgb())
|
||||
setTextColor(onSurface.toArgb())
|
||||
setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, textStyle.fontSize.value)
|
||||
background = android.graphics.drawable.GradientDrawable().apply {
|
||||
setColor(surfaceVariant.toArgb())
|
||||
cornerRadius = with(density) { 8.dp.toPx() }
|
||||
}
|
||||
setPadding(
|
||||
with(density) { 16.dp.toPx().toInt() },
|
||||
with(density) { 12.dp.toPx().toInt() },
|
||||
with(density) { 16.dp.toPx().toInt() },
|
||||
with(density) { 12.dp.toPx().toInt() },
|
||||
)
|
||||
maxLines = 8
|
||||
inputType = android.text.InputType.TYPE_CLASS_TEXT or
|
||||
android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE or
|
||||
android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
|
||||
isSingleLine = false
|
||||
|
||||
// Prevent EditText from fighting with Compose's imePadding()
|
||||
imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_EXTRACT_UI
|
||||
|
||||
addTextChangedListener(object : android.text.TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
||||
override fun afterTextChanged(s: android.text.Editable?) {
|
||||
text = s?.toString() ?: ""
|
||||
}
|
||||
})
|
||||
|
||||
androidx.core.view.ViewCompat.setOnReceiveContentListener(
|
||||
this,
|
||||
arrayOf("image/*"),
|
||||
) { _, payload ->
|
||||
val clip = payload.clip
|
||||
var remaining = payload
|
||||
for (i in 0 until clip.itemCount) {
|
||||
val uri = clip.getItemAt(i).uri
|
||||
if (uri != null) {
|
||||
attachedUris = attachedUris + uri
|
||||
}
|
||||
}
|
||||
// Return null to indicate all content was consumed
|
||||
if (clip.itemCount > 0 && (0 until clip.itemCount).any { clip.getItemAt(it).uri != null }) null
|
||||
else remaining
|
||||
}
|
||||
}
|
||||
},
|
||||
update = { editText ->
|
||||
if (editText.text.toString() != text) {
|
||||
editText.setText(text)
|
||||
editText.setSelection(text.length)
|
||||
}
|
||||
editText.hint = "Message #$channelName"
|
||||
},
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.heightIn(max = 160.dp),
|
||||
)
|
||||
if (emojiPacks.isNotEmpty()) {
|
||||
IconButton(onClick = { showEmojiPackPicker = true }) {
|
||||
|
||||
Reference in New Issue
Block a user