feat: Optimize chat screen transitions by removing redundant animations for a smoother user experience
This commit is contained in:
@@ -6,6 +6,9 @@ import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.core.FastOutLinearInEasing
|
||||
import androidx.compose.animation.core.LinearOutSlowInEasing
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.Spring
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.animation.core.tween
|
||||
@@ -234,7 +237,7 @@ fun MainScreen(
|
||||
var selectedUser by remember { mutableStateOf<SearchUser?>(null) }
|
||||
var showSearchScreen by remember { mutableStateOf(false) }
|
||||
|
||||
// Анимированный переход между экранами - Telegram-style
|
||||
// 🔥 TELEGRAM-STYLE анимация - чистый slide БЕЗ прозрачности
|
||||
AnimatedContent(
|
||||
targetState = Triple(selectedUser, showSearchScreen, Unit),
|
||||
transitionSpec = {
|
||||
@@ -244,113 +247,79 @@ fun MainScreen(
|
||||
val isExitingSearch = !targetState.second && initialState.second
|
||||
|
||||
when {
|
||||
// 🚀 Вход в чат - slide справа + fade (как Telegram)
|
||||
// 🚀 Вход в чат - чистый slide справа (как Telegram/iOS)
|
||||
// Новый экран полностью покрывает старый, никакой прозрачности
|
||||
isEnteringChat -> {
|
||||
slideInHorizontally(
|
||||
initialOffsetX = { fullWidth -> fullWidth / 3 }, // Начинаем на 1/3 экрана справа
|
||||
animationSpec = tween(
|
||||
durationMillis = 250,
|
||||
easing = FastOutSlowInEasing
|
||||
)
|
||||
) + fadeIn(
|
||||
initialAlpha = 0.3f,
|
||||
animationSpec = tween(
|
||||
durationMillis = 200,
|
||||
easing = FastOutSlowInEasing
|
||||
initialOffsetX = { fullWidth -> fullWidth }, // Начинаем за экраном справа
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioNoBouncy,
|
||||
stiffness = Spring.StiffnessMediumLow // Плавно но быстро
|
||||
)
|
||||
) togetherWith slideOutHorizontally(
|
||||
targetOffsetX = { fullWidth -> -fullWidth / 6 }, // Список уходит немного влево
|
||||
animationSpec = tween(
|
||||
durationMillis = 250,
|
||||
easing = FastOutSlowInEasing
|
||||
)
|
||||
) + fadeOut(
|
||||
targetAlpha = 0.5f,
|
||||
animationSpec = tween(
|
||||
durationMillis = 200,
|
||||
easing = FastOutSlowInEasing
|
||||
targetOffsetX = { fullWidth -> -fullWidth / 4 }, // Старый экран уходит влево на 25%
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioNoBouncy,
|
||||
stiffness = Spring.StiffnessMediumLow
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// 🔙 Выход из чата - slide вправо + fade (быстрее)
|
||||
// 🔙 Выход из чата - обратный slide
|
||||
isExitingChat -> {
|
||||
slideInHorizontally(
|
||||
initialOffsetX = { fullWidth -> -fullWidth / 6 }, // Список возвращается слева
|
||||
animationSpec = tween(
|
||||
durationMillis = 200,
|
||||
easing = FastOutSlowInEasing
|
||||
)
|
||||
) + fadeIn(
|
||||
initialAlpha = 0.5f,
|
||||
animationSpec = tween(
|
||||
durationMillis = 180,
|
||||
easing = FastOutSlowInEasing
|
||||
initialOffsetX = { fullWidth -> -fullWidth / 4 }, // Список возвращается слева
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioNoBouncy,
|
||||
stiffness = Spring.StiffnessMedium // Чуть быстрее при выходе
|
||||
)
|
||||
) togetherWith slideOutHorizontally(
|
||||
targetOffsetX = { fullWidth -> fullWidth / 2 }, // Чат уходит вправо
|
||||
animationSpec = tween(
|
||||
durationMillis = 200,
|
||||
easing = FastOutSlowInEasing
|
||||
)
|
||||
) + fadeOut(
|
||||
animationSpec = tween(
|
||||
durationMillis = 180,
|
||||
easing = FastOutSlowInEasing
|
||||
targetOffsetX = { fullWidth -> fullWidth }, // Чат уходит за экран вправо
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioNoBouncy,
|
||||
stiffness = Spring.StiffnessMedium
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// 🔍 Вход в поиск - slide снизу
|
||||
// 🔍 Вход в поиск - slide сверху
|
||||
isEnteringSearch -> {
|
||||
slideInVertically(
|
||||
initialOffsetY = { fullHeight -> fullHeight / 4 },
|
||||
animationSpec = tween(
|
||||
durationMillis = 220,
|
||||
easing = FastOutSlowInEasing
|
||||
)
|
||||
) + fadeIn(
|
||||
animationSpec = tween(
|
||||
durationMillis = 200,
|
||||
easing = FastOutSlowInEasing
|
||||
)
|
||||
) togetherWith fadeOut(
|
||||
animationSpec = tween(
|
||||
durationMillis = 150,
|
||||
easing = FastOutSlowInEasing
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// ❌ Выход из поиска - slide вниз
|
||||
isExitingSearch -> {
|
||||
fadeIn(
|
||||
animationSpec = tween(
|
||||
durationMillis = 180,
|
||||
easing = FastOutSlowInEasing
|
||||
initialOffsetY = { -it },
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioNoBouncy,
|
||||
stiffness = Spring.StiffnessMediumLow
|
||||
)
|
||||
) togetherWith slideOutVertically(
|
||||
targetOffsetY = { fullHeight -> fullHeight / 4 },
|
||||
animationSpec = tween(
|
||||
durationMillis = 200,
|
||||
easing = FastOutSlowInEasing
|
||||
)
|
||||
) + fadeOut(
|
||||
animationSpec = tween(
|
||||
durationMillis = 150,
|
||||
easing = FastOutSlowInEasing
|
||||
targetOffsetY = { it / 4 },
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioNoBouncy,
|
||||
stiffness = Spring.StiffnessMediumLow
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// Default fade
|
||||
else -> {
|
||||
fadeIn(
|
||||
animationSpec = tween(durationMillis = 200)
|
||||
) togetherWith fadeOut(
|
||||
animationSpec = tween(durationMillis = 150)
|
||||
// ❌ Выход из поиска
|
||||
isExitingSearch -> {
|
||||
slideInVertically(
|
||||
initialOffsetY = { it / 4 },
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioNoBouncy,
|
||||
stiffness = Spring.StiffnessMedium
|
||||
)
|
||||
) togetherWith slideOutVertically(
|
||||
targetOffsetY = { -it },
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioNoBouncy,
|
||||
stiffness = Spring.StiffnessMedium
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// Default - мгновенный переход
|
||||
else -> {
|
||||
EnterTransition.None togetherWith ExitTransition.None
|
||||
}
|
||||
}
|
||||
},
|
||||
label = "screenNavigation"
|
||||
|
||||
Reference in New Issue
Block a user