Refactor(TopBar): Optimize TopBar

Optimize TopBar in AboutScreen and LibrariesScreen
This commit is contained in:
2024-04-25 11:18:11 +08:00
parent 32d19ae291
commit 61d229b100
5 changed files with 122 additions and 86 deletions

View File

@@ -4,19 +4,31 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.material3.Icon import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.IconButton import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource import androidx.compose.ui.res.vectorResource
@@ -24,6 +36,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import top.fatweb.oxygen.toolbox.R import top.fatweb.oxygen.toolbox.R
import top.fatweb.oxygen.toolbox.icon.OxygenIcons import top.fatweb.oxygen.toolbox.icon.OxygenIcons
import top.fatweb.oxygen.toolbox.ui.component.OxygenTopAppBar
import top.fatweb.oxygen.toolbox.ui.theme.OxygenPreviews import top.fatweb.oxygen.toolbox.ui.theme.OxygenPreviews
import top.fatweb.oxygen.toolbox.ui.theme.OxygenTheme import top.fatweb.oxygen.toolbox.ui.theme.OxygenTheme
import top.fatweb.oxygen.toolbox.ui.util.ResourcesUtils import top.fatweb.oxygen.toolbox.ui.util.ResourcesUtils
@@ -39,16 +52,47 @@ internal fun AboutRoute(
) )
} }
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
internal fun AboutScreen( internal fun AboutScreen(
modifier: Modifier = Modifier, onBackClick: () -> Unit, onNavigateToLibraries: () -> Unit modifier: Modifier = Modifier, onBackClick: () -> Unit, onNavigateToLibraries: () -> Unit
) { ) {
Column( val scrollState = rememberScrollState()
modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally val topAppBarScrollBehavior =
) { TopAppBarDefaults.enterAlwaysScrollBehavior(canScroll = { scrollState.maxValue > 0 })
AboutToolBar(
onBackClick = onBackClick Scaffold(
modifier = Modifier
.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection),
containerColor = Color.Transparent,
contentWindowInsets = WindowInsets(0, 0, 0, 0),
topBar = {
OxygenTopAppBar(
scrollBehavior = topAppBarScrollBehavior,
titleRes = R.string.feature_settings_more_about,
navigationIcon = OxygenIcons.Back,
navigationIconContentDescription = stringResource(R.string.core_back),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent,
scrolledContainerColor = Color.Transparent
),
onNavigationClick = onBackClick
) )
}
) { padding ->
Column(
modifier = modifier
.fillMaxWidth()
.fillMaxHeight()
.padding(padding)
.consumeWindowInsets(padding)
.windowInsetsPadding(
WindowInsets.safeDrawing.only(
WindowInsetsSides.Horizontal
)
)
.verticalScroll(scrollState), horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer( Spacer(
modifier = Modifier.height(64.dp) modifier = Modifier.height(64.dp)
) )
@@ -61,24 +105,6 @@ internal fun AboutScreen(
) )
} }
} }
@Composable
private fun AboutToolBar(
modifier: Modifier = Modifier, onBackClick: () -> Unit
) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
IconButton(onClick = onBackClick) {
Icon(
imageVector = OxygenIcons.ArrowBack,
contentDescription = stringResource(R.string.core_back)
)
}
}
} }
@Composable @Composable
@@ -136,14 +162,6 @@ private fun AboutFooter(
} }
} }
@OxygenPreviews
@Composable
fun AboutToolBarPreview() {
OxygenTheme {
AboutToolBar(onBackClick = {})
}
}
@OxygenPreviews @OxygenPreviews
@Composable @Composable
fun AboutAppInfoPreview() { fun AboutAppInfoPreview() {

View File

@@ -11,10 +11,13 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.safeDrawingPadding
@@ -29,11 +32,12 @@ import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridS
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Icon import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@@ -41,6 +45,8 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -49,6 +55,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import top.fatweb.oxygen.toolbox.R import top.fatweb.oxygen.toolbox.R
import top.fatweb.oxygen.toolbox.icon.OxygenIcons import top.fatweb.oxygen.toolbox.icon.OxygenIcons
import top.fatweb.oxygen.toolbox.ui.component.OxygenTopAppBar
import top.fatweb.oxygen.toolbox.ui.component.scrollbar.DraggableScrollbar import top.fatweb.oxygen.toolbox.ui.component.scrollbar.DraggableScrollbar
import top.fatweb.oxygen.toolbox.ui.component.scrollbar.rememberDraggableScroller import top.fatweb.oxygen.toolbox.ui.component.scrollbar.rememberDraggableScroller
import top.fatweb.oxygen.toolbox.ui.component.scrollbar.scrollbarState import top.fatweb.oxygen.toolbox.ui.component.scrollbar.scrollbarState
@@ -70,6 +77,7 @@ internal fun LibrariesRoute(
) )
} }
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
internal fun LibrariesScreen( internal fun LibrariesScreen(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@@ -93,16 +101,39 @@ internal fun LibrariesScreen(
var dialogContent by remember { mutableStateOf("") } var dialogContent by remember { mutableStateOf("") }
var dialogUrl by remember { mutableStateOf("") } var dialogUrl by remember { mutableStateOf("") }
Column( val topAppBarScrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
modifier = modifier
) { Scaffold(
LibrariesToolBar( modifier = Modifier
onBackClick = onBackClick .nestedScroll(topAppBarScrollBehavior.nestedScrollConnection),
containerColor = Color.Transparent,
contentWindowInsets = WindowInsets(0, 0, 0, 0),
topBar = {
OxygenTopAppBar(
scrollBehavior = topAppBarScrollBehavior,
titleRes = R.string.feature_settings_open_source_license,
navigationIcon = OxygenIcons.Back,
navigationIconContentDescription = stringResource(R.string.core_back),
actionIcon = OxygenIcons.Search,
actionIconContentDescription = stringResource(R.string.core_search),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent,
scrolledContainerColor = Color.Transparent
),
onNavigationClick = onBackClick
) )
}
) { padding ->
Box( Box(
modifier modifier
.fillMaxWidth() .fillMaxWidth()
.weight(1f) .padding(padding)
.consumeWindowInsets(padding)
.windowInsetsPadding(
WindowInsets.safeDrawing.only(
WindowInsetsSides.Horizontal
)
)
) { ) {
when (librariesScreenUiState) { when (librariesScreenUiState) {
LibrariesScreenUiState.Loading -> { LibrariesScreenUiState.Loading -> {
@@ -192,25 +223,6 @@ internal fun LibrariesScreen(
} }
} }
@Composable
private fun LibrariesToolBar(
modifier: Modifier = Modifier, onBackClick: () -> Unit
) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
IconButton(onClick = onBackClick) {
Icon(
imageVector = OxygenIcons.ArrowBack,
contentDescription = stringResource(R.string.core_back)
)
}
}
}
fun howManyItems(librariesScreenUiState: LibrariesScreenUiState) = fun howManyItems(librariesScreenUiState: LibrariesScreenUiState) =
when (librariesScreenUiState) { when (librariesScreenUiState) {
LibrariesScreenUiState.Loading -> 0 LibrariesScreenUiState.Loading -> 0

View File

@@ -30,10 +30,10 @@ fun OxygenTopAppBar(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
scrollBehavior: TopAppBarScrollBehavior? = null, scrollBehavior: TopAppBarScrollBehavior? = null,
@StringRes titleRes: Int, @StringRes titleRes: Int,
navigationIcon: ImageVector, navigationIcon: ImageVector? = null,
navigationIconContentDescription: String, navigationIconContentDescription: String? = null,
actionIcon: ImageVector, actionIcon: ImageVector? = null,
actionIconContentDescription: String, actionIconContentDescription: String? = null,
colors: TopAppBarColors = TopAppBarDefaults.centerAlignedTopAppBarColors(), colors: TopAppBarColors = TopAppBarDefaults.centerAlignedTopAppBarColors(),
onNavigationClick: () -> Unit = {}, onNavigationClick: () -> Unit = {},
onActionClick: () -> Unit = {} onActionClick: () -> Unit = {}
@@ -47,6 +47,7 @@ fun OxygenTopAppBar(
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
title = { Text(stringResource(titleRes)) }, title = { Text(stringResource(titleRes)) },
navigationIcon = { navigationIcon = {
navigationIcon?.let {
IconButton(onClick = onNavigationClick) { IconButton(onClick = onNavigationClick) {
Icon( Icon(
imageVector = navigationIcon, imageVector = navigationIcon,
@@ -54,8 +55,10 @@ fun OxygenTopAppBar(
tint = MaterialTheme.colorScheme.onSurface tint = MaterialTheme.colorScheme.onSurface
) )
} }
}
}, },
actions = { actions = {
actionIcon?.let {
IconButton(onClick = onActionClick) { IconButton(onClick = onActionClick) {
Icon( Icon(
imageVector = actionIcon, imageVector = actionIcon,
@@ -63,6 +66,7 @@ fun OxygenTopAppBar(
tint = MaterialTheme.colorScheme.onSurface tint = MaterialTheme.colorScheme.onSurface
) )
} }
}
}, },
colors = colors, colors = colors,
windowInsets = WindowInsets(top = topInset) windowInsets = WindowInsets(top = topInset)

View File

@@ -8,6 +8,7 @@
<string name="core_close">关闭</string> <string name="core_close">关闭</string>
<string name="core_unknown">未知</string> <string name="core_unknown">未知</string>
<string name="core_website">网站</string> <string name="core_website">网站</string>
<string name="core_search">搜索</string>
<string name="core_no_connect">⚠️ 无法连接至互联网</string> <string name="core_no_connect">⚠️ 无法连接至互联网</string>
<string name="feature_tools_title">工具</string> <string name="feature_tools_title">工具</string>
<string name="feature_star_title">收藏</string> <string name="feature_star_title">收藏</string>

View File

@@ -7,6 +7,7 @@
<string name="core_close">Close</string> <string name="core_close">Close</string>
<string name="core_unknown">Unknown</string> <string name="core_unknown">Unknown</string>
<string name="core_website">Website</string> <string name="core_website">Website</string>
<string name="core_search">Search</string>
<string name="core_no_connect">⚠️ Unable to connect to the internet</string> <string name="core_no_connect">⚠️ Unable to connect to the internet</string>
<string name="feature_tools_title">Tools</string> <string name="feature_tools_title">Tools</string>
<string name="feature_star_title">Star</string> <string name="feature_star_title">Star</string>