Added animated visibility to the FloatingBar component

This commit is contained in:
Arty Bishop committed 2025-12-27 15:02:14 +00:00
1 parent 34e66f9ae0
commit fb8053ef60
3 files changed
+31 -13

No files matched your search

@@ -117,8 +117,8 @@ private val shapes = Shapes(
extraSmall = RoundedCornerShape(4.dp), // menus, snackbars, text fields extraSmall = RoundedCornerShape(4.dp), // menus, snackbars, text fields
small = RoundedCornerShape(6.dp), // buttons, chips small = RoundedCornerShape(6.dp), // buttons, chips
medium = RoundedCornerShape(8.dp), // cards, small FABs medium = RoundedCornerShape(8.dp), // cards, small FABs
large = RoundedCornerShape(12.dp), // extended FABs, FABs, nav drawers large = RoundedCornerShape(24.dp), // extended FABs, FABs, nav drawers
extraLarge = RoundedCornerShape(16.dp) // large FABs extraLarge = RoundedCornerShape(32.dp) // large FABs
) )
private val typography = Typography( private val typography = Typography(
@@ -1,5 +1,9 @@
package com.rtbishop.look4sat.presentation.passes package com.rtbishop.look4sat.presentation.passes
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@@ -12,8 +16,10 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.material3.ElevatedCard import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@@ -25,6 +31,8 @@ import androidx.compose.material3.pulltorefresh.PullToRefreshBox
import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@@ -97,7 +105,10 @@ private fun PassesScreen(uiState: PassesState, navActions: NavActions) {
uiState.takeAction(PassesAction.DismissWelcome) uiState.takeAction(PassesAction.DismissWelcome)
} }
} }
ScreenColumn(floatingBar = { PassesFloatingBar(navActions) }) { isVerticalLayout -> val gridState = rememberLazyGridState()
ScreenColumn(
floatingBar = { PassesFloatingBar(gridState.isScrolling(), navActions) }
) { isVerticalLayout ->
if (isVerticalLayout) { if (isVerticalLayout) {
TopBar { TopBar {
IconCard(action = { showPassesDialog() }, resId = R.drawable.ic_filter) IconCard(action = { showPassesDialog() }, resId = R.drawable.ic_filter)
@@ -113,17 +124,19 @@ private fun PassesScreen(uiState: PassesState, navActions: NavActions) {
IconCard(action = { showRadiosDialog() }, resId = R.drawable.ic_satellite) IconCard(action = { showRadiosDialog() }, resId = R.drawable.ic_satellite)
} }
} }
PassesList(uiState.isRefreshing, uiState.itemsList, navActions.openRadar, refreshList) PassesList(uiState.isRefreshing, uiState.itemsList, navActions.openRadar, refreshList, gridState)
} }
} }
@Composable @Composable
private fun PassesFloatingBar(navActions: NavActions) { private fun PassesFloatingBar(visible: Boolean, navActions: NavActions) {
AnimatedVisibility(visible = visible, enter = fadeIn(tween(250)), exit = fadeOut(tween(250))) {
FloatingBar( FloatingBar(
startAction = navActions.openSettings, startIconResId = R.drawable.ic_settings, startAction = navActions.openSettings, startIconResId = R.drawable.ic_settings,
centerAction = navActions.openSatellites, centerIconResId = R.drawable.ic_sputnik, centerAction = navActions.openSatellites, centerIconResId = R.drawable.ic_sputnik,
endAction = navActions.openMap, endIconResId = R.drawable.ic_map endAction = navActions.openMap, endIconResId = R.drawable.ic_map
) )
}
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@@ -132,7 +145,8 @@ private fun PassesList(
isRefreshing: Boolean, isRefreshing: Boolean,
passes: List<OrbitalPass>, passes: List<OrbitalPass>,
navigateToRadar: (Int, Long) -> Unit, navigateToRadar: (Int, Long) -> Unit,
refreshPasses: () -> Unit refreshPasses: () -> Unit,
gridState: LazyGridState
) { ) {
val isVerticalLayout = isVerticalLayout() val isVerticalLayout = isVerticalLayout()
val refreshState = rememberPullToRefreshState() val refreshState = rememberPullToRefreshState()
@@ -155,6 +169,7 @@ private fun PassesList(
EmptyListCard(message = stringResource(R.string.passes_empty_list_message)) EmptyListCard(message = stringResource(R.string.passes_empty_list_message))
} else { } else {
LazyVerticalGrid( LazyVerticalGrid(
state = gridState,
columns = GridCells.Adaptive(320.dp), columns = GridCells.Adaptive(320.dp),
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()
) { ) {
@@ -310,3 +325,8 @@ private fun NearEarthPass(
} }
} }
} }
@Composable
private fun LazyGridState.isScrolling(): Boolean {
return remember { derivedStateOf { !isScrollInProgress } }.value
}
+5 -7
View File
@@ -5,13 +5,12 @@ kotlin = "2.2.20"
androidx-core-ktx = "1.17.0" androidx-core-ktx = "1.17.0"
androidx-core-splashscreen = "1.0.1" androidx-core-splashscreen = "1.0.1"
androidx-room = "2.8.0" androidx-room = "2.8.1"
compose-bom = "2025.09.00" compose-bom = "2025.09.01"
compose-activity = "1.11.0" compose-activity = "1.11.0"
compose-lifecycle = "2.9.3" compose-lifecycle = "2.9.4"
#compose-material3 = "1.4.0-rc01" compose-navigation = "2.9.5"
compose-navigation = "2.9.4"
other-coroutines = "1.10.2" other-coroutines = "1.10.2"
other-json = "20250517" other-json = "20250517"
@@ -19,7 +18,7 @@ other-okhttp = "5.1.0"
other-osmdroid = "6.1.20" other-osmdroid = "6.1.20"
test-junit4 = "4.13.2" test-junit4 = "4.13.2"
test-mockk = "1.14.5" test-mockk = "1.14.6"
androidTest-junit = "1.3.0" androidTest-junit = "1.3.0"
androidTest-espresso = "3.7.0" androidTest-espresso = "3.7.0"
@@ -40,7 +39,6 @@ compose-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
compose-activity = { module = "androidx.activity:activity-compose", version.ref = "compose-activity" } compose-activity = { module = "androidx.activity:activity-compose", version.ref = "compose-activity" }
compose-lifecycle = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "compose-lifecycle" } compose-lifecycle = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "compose-lifecycle" }
#compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose-material3" }
compose-navigation = { module = "androidx.navigation:navigation-compose", version.ref = "compose-navigation" } compose-navigation = { module = "androidx.navigation:navigation-compose", version.ref = "compose-navigation" }
compose-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "compose-lifecycle" } compose-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "compose-lifecycle" }