feat(nav+fav): порядок меню, анимация иконки при выборе, индикатор на избранном
- Порядок нижнего меню: Радио · Избранное · История · Чарты · Запись · Настройки. - Иконка вкладки при выборе делает упругий scale-«поп» (spring MediumBouncy) — в нижнем баре и боковом рейле. - На экране «Избранное» играющая станция теперь подсвечивается так же, как на главной: вращающееся свечение под обложкой + индикатор-эквалайзер в углу (FavoritesViewModel отдаёт playingStationId/isPlaying из PlayerController, FavoritesScreen передаёт isCurrent/isPlaying в StationCard).
This commit is contained in:
@@ -2,6 +2,9 @@ package com.radiola.ui.navigation
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.Spring
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.expandHorizontally
|
||||
import androidx.compose.animation.fadeIn
|
||||
@@ -28,11 +31,13 @@ import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
@@ -43,9 +48,9 @@ import com.radiola.ui.theme.RadiolaTheme
|
||||
// при холодном старте может содержать null (порядок инициализации Kotlin).
|
||||
private val navItems = listOf(
|
||||
NavDestinations.Stations,
|
||||
NavDestinations.Charts,
|
||||
NavDestinations.Favorites,
|
||||
NavDestinations.History,
|
||||
NavDestinations.Charts,
|
||||
NavDestinations.Recordings,
|
||||
NavDestinations.Settings
|
||||
)
|
||||
@@ -144,6 +149,13 @@ private fun VerticalPillTab(
|
||||
animationSpec = tween(Motion.Medium),
|
||||
label = "railTabFg"
|
||||
)
|
||||
val pop = remember { Animatable(1f) }
|
||||
LaunchedEffect(selected) {
|
||||
if (selected) {
|
||||
pop.snapTo(0.5f)
|
||||
pop.animateTo(1f, spring(dampingRatio = Spring.DampingRatioMediumBouncy, stiffness = 620f))
|
||||
}
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.size(52.dp)
|
||||
@@ -161,7 +173,7 @@ private fun VerticalPillTab(
|
||||
imageVector = icon,
|
||||
contentDescription = label,
|
||||
tint = content,
|
||||
modifier = Modifier.size(22.dp)
|
||||
modifier = Modifier.size(22.dp).scale(pop.value)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -185,6 +197,14 @@ private fun PillTab(
|
||||
animationSpec = tween(Motion.Medium),
|
||||
label = "tabFg"
|
||||
)
|
||||
// Упругий «поп» иконки при выборе вкладки — маленькая приятная деталь.
|
||||
val pop = remember { Animatable(1f) }
|
||||
LaunchedEffect(selected) {
|
||||
if (selected) {
|
||||
pop.snapTo(0.5f)
|
||||
pop.animateTo(1f, spring(dampingRatio = Spring.DampingRatioMediumBouncy, stiffness = 620f))
|
||||
}
|
||||
}
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
@@ -204,7 +224,7 @@ private fun PillTab(
|
||||
imageVector = icon,
|
||||
contentDescription = label,
|
||||
tint = content,
|
||||
modifier = Modifier.height(22.dp).width(22.dp)
|
||||
modifier = Modifier.height(22.dp).width(22.dp).scale(pop.value)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user