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