diff options
| author | saber safavi <saber.safavi@codic.se> | 2023-06-28 16:23:05 +0200 |
|---|---|---|
| committer | saber safavi <saber.safavi@codic.se> | 2023-07-06 12:26:00 +0200 |
| commit | e25edb6afb9d5869ee593b46a14018cc55d0dbec (patch) | |
| tree | 9c031787ba1bc4a33babf1a9c99ecbce5278636d /android | |
| parent | cc940e2ea9cd9034a99ff1857beccac3cde6e6f6 (diff) | |
| download | mullvadvpn-e25edb6afb9d5869ee593b46a14018cc55d0dbec.tar.xz mullvadvpn-e25edb6afb9d5869ee593b46a14018cc55d0dbec.zip | |
Add collapsible toolbar component with dynamic body height
Diffstat (limited to 'android')
4 files changed, 94 insertions, 7 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingToolbarScaffold.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingToolbarScaffold.kt new file mode 100644 index 0000000000..f4b81826bc --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingToolbarScaffold.kt @@ -0,0 +1,88 @@ +package net.mullvad.mullvadvpn.compose.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.dp +import com.google.accompanist.systemuicontroller.rememberSystemUiController +import me.onebone.toolbar.CollapsingToolbarScaffold +import me.onebone.toolbar.CollapsingToolbarScaffoldScope +import me.onebone.toolbar.CollapsingToolbarScaffoldState +import me.onebone.toolbar.CollapsingToolbarScope +import me.onebone.toolbar.ExperimentalToolbarApi +import me.onebone.toolbar.ScrollStrategy + +@OptIn(ExperimentalToolbarApi::class) +@Composable +fun CollapsingToolbarScaffold( + backgroundColor: Color, + state: CollapsingToolbarScaffoldState, + modifier: Modifier = Modifier, + scrollStrategy: ScrollStrategy = ScrollStrategy.ExitUntilCollapsed, + isEnabledWhenCollapsable: Boolean = true, + toolbarModifier: Modifier = Modifier, + toolbar: @Composable CollapsingToolbarScope.() -> Unit, + body: @Composable CollapsingToolbarScaffoldScope.() -> Unit, +) { + val dynamic = remember { mutableStateOf(0.dp) } + val systemUiController = rememberSystemUiController() + systemUiController.setStatusBarColor(backgroundColor) + systemUiController.setNavigationBarColor(backgroundColor) + + var isCollapsable by remember { mutableStateOf(false) } + + LaunchedEffect(isCollapsable) { + if (!isCollapsable) { + state.toolbarState.expand() + } + } + val totalHeights = remember { mutableStateOf(0.dp) } + val localDensity = LocalDensity.current + + CollapsingToolbarScaffold( + modifier = + modifier + .background(backgroundColor) + .fillMaxWidth() + .fillMaxHeight() + .onGloballyPositioned { coordinates -> + totalHeights.value = with(localDensity) { coordinates.size.height.toDp() } + }, + state = state, + scrollStrategy = scrollStrategy, + toolbarModifier = + toolbarModifier.onGloballyPositioned { coordinates -> + with(localDensity) { + dynamic.value = totalHeights.value - coordinates.size.height.toDp() + } + }, + enabled = isEnabledWhenCollapsable && isCollapsable, + toolbar = { toolbar() } + ) { + var bodyHeight by remember { mutableStateOf(0) } + + BoxWithConstraints( + modifier = + Modifier.height(dynamic.value).onGloballyPositioned { bodyHeight = it.size.height } + ) { + val minMaxToolbarHeightDiff = + with(state) { toolbarState.maxHeight - toolbarState.minHeight } + val isContentHigherThanCollapseThreshold = + with(localDensity) { bodyHeight >= maxHeight.toPx() - minMaxToolbarHeightDiff } + isCollapsable = isContentHigherThanCollapseThreshold + body() + } + } +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt index 6dd3435e64..0af698e61c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt @@ -23,7 +23,7 @@ import me.onebone.toolbar.ScrollStrategy import me.onebone.toolbar.rememberCollapsingToolbarScaffoldState import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.cell.RelayLocationCell -import net.mullvad.mullvadvpn.compose.component.CollapsableAwareToolbarScaffold +import net.mullvad.mullvadvpn.compose.component.CollapsingToolbarScaffold import net.mullvad.mullvadvpn.compose.component.CollapsingTopBar import net.mullvad.mullvadvpn.compose.constant.ContentType import net.mullvad.mullvadvpn.compose.state.SelectLocationUiState @@ -54,7 +54,7 @@ fun SelectLocationScreen( val state = rememberCollapsingToolbarScaffoldState() val progress = state.toolbarState.progress LaunchedEffect(Unit) { uiCloseAction.collect { onBackClick() } } - CollapsableAwareToolbarScaffold( + CollapsingToolbarScaffold( backgroundColor = MaterialTheme.colorScheme.background, modifier = Modifier.fillMaxSize(), state = state, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt index e624170479..a690ba3ae1 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt @@ -26,7 +26,7 @@ import net.mullvad.mullvadvpn.applist.AppData import net.mullvad.mullvadvpn.compose.cell.BaseCell import net.mullvad.mullvadvpn.compose.cell.HeaderSwitchComposeCell import net.mullvad.mullvadvpn.compose.cell.SplitTunnelingCell -import net.mullvad.mullvadvpn.compose.component.CollapsableAwareToolbarScaffold +import net.mullvad.mullvadvpn.compose.component.CollapsingToolbarScaffold import net.mullvad.mullvadvpn.compose.component.CollapsingTopBar import net.mullvad.mullvadvpn.compose.component.drawVerticalScrollbar import net.mullvad.mullvadvpn.compose.constant.CommonContentKey @@ -36,7 +36,6 @@ import net.mullvad.mullvadvpn.compose.extensions.itemWithDivider import net.mullvad.mullvadvpn.compose.state.SplitTunnelingUiState import net.mullvad.mullvadvpn.compose.theme.AppTheme import net.mullvad.mullvadvpn.compose.theme.Dimens -import org.koin.androidx.compose.get @Preview @Composable @@ -86,7 +85,7 @@ fun SplitTunnelingScreen( val progress = state.toolbarState.progress val lazyListState = rememberLazyListState() - CollapsableAwareToolbarScaffold( + CollapsingToolbarScaffold( backgroundColor = MaterialTheme.colorScheme.background, modifier = Modifier.fillMaxSize(), state = state, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt index 735c9464dc..bc44670940 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt @@ -53,7 +53,7 @@ import net.mullvad.mullvadvpn.compose.cell.InformationComposeCell import net.mullvad.mullvadvpn.compose.cell.MtuComposeCell import net.mullvad.mullvadvpn.compose.cell.NormalSwitchComposeCell import net.mullvad.mullvadvpn.compose.cell.SelectableCell -import net.mullvad.mullvadvpn.compose.component.CollapsableAwareToolbarScaffold +import net.mullvad.mullvadvpn.compose.component.CollapsingToolbarScaffold import net.mullvad.mullvadvpn.compose.component.CollapsingTopBar import net.mullvad.mullvadvpn.compose.component.drawVerticalScrollbar import net.mullvad.mullvadvpn.compose.dialog.ContentBlockersInfoDialog @@ -211,7 +211,7 @@ fun VpnSettingsScreen( val state = rememberCollapsingToolbarScaffoldState() val progress = state.toolbarState.progress - CollapsableAwareToolbarScaffold( + CollapsingToolbarScaffold( backgroundColor = MaterialTheme.colorScheme.background, modifier = Modifier.fillMaxSize(), state = state, |
