Сделал скрытие клавиатуры на back-свайпе во всех экранах

This commit is contained in:
2026-03-19 16:19:06 +05:00
parent 4640b0128f
commit 13b61cf720

View File

@@ -1,5 +1,6 @@
package com.rosetta.messenger.ui.components
import android.app.Activity
import android.content.Context
import android.view.animation.DecelerateInterpolator
import android.view.inputmethod.InputMethodManager
@@ -20,9 +21,11 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlin.coroutines.coroutineContext
// Telegram's CubicBezierInterpolator(0.25, 0.1, 0.25, 1.0)
@@ -174,6 +177,15 @@ fun SwipeBackContainer(
val context = LocalContext.current
val view = LocalView.current
val focusManager = LocalFocusManager.current
val dismissKeyboard: () -> Unit = {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.windowToken, 0)
imm.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
(view.context as? Activity)?.window?.let { window ->
WindowCompat.getInsetsController(window, view).hide(WindowInsetsCompat.Type.ime())
}
focusManager.clearFocus(force = true)
}
// Current offset: use drag offset during drag, animatable otherwise + optional enter slide
val baseOffset = if (isDragging) dragOffset else offsetAnimatable.value
@@ -333,6 +345,7 @@ fun SwipeBackContainer(
var totalDragX = 0f
var totalDragY = 0f
var passedSlop = false
var keyboardHiddenForGesture = false
// deferToChildren=true: pre-slop uses Main pass so children
// (e.g. LazyRow) process first — if they consume, we back off.
@@ -359,6 +372,14 @@ fun SwipeBackContainer(
totalDragX += dragDelta.x
totalDragY += dragDelta.y
if (!keyboardHiddenForGesture &&
totalDragX > 10f &&
kotlin.math.abs(totalDragX) >
kotlin.math.abs(totalDragY)) {
dismissKeyboard()
keyboardHiddenForGesture = true
}
if (!passedSlop) {
// Child (e.g. LazyRow) already consumed — let it handle
if (change.isConsumed) break
@@ -393,17 +414,8 @@ fun SwipeBackContainer(
screenWidthPx,
active = true
)
val imm =
context.getSystemService(
Context.INPUT_METHOD_SERVICE
) as
InputMethodManager
imm.hideSoftInputFromWindow(
view.windowToken,
0
)
focusManager.clearFocus()
dismissKeyboard()
keyboardHiddenForGesture = true
change.consume()
} else {
@@ -489,6 +501,7 @@ fun SwipeBackContainer(
shouldShow = false
dragOffset = 0f
clearSharedSwipeProgressIfOwner()
dismissKeyboard()
onBack()
} else {
offsetAnimatable.animateTo(