优化关于界面显示

This commit is contained in:
HapeLee
2025-11-23 15:34:47 +08:00
parent 5ffcb2f5fe
commit e9ccf3b700
3 changed files with 135 additions and 90 deletions
@@ -3,20 +3,18 @@ package io.legado.app.ui.about
import android.content.res.Configuration import android.content.res.Configuration
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
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.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ButtonGroup
import androidx.compose.material3.ButtonGroupDefaults
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FilledTonalIconButton import androidx.compose.material3.FilledTonalIconButton
@@ -26,7 +24,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@@ -35,8 +32,10 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.AppTheme import io.legado.app.base.AppTheme
import io.legado.app.constant.AppConst.appInfo import io.legado.app.constant.AppConst.appInfo
@@ -61,61 +60,6 @@ fun PreviewAboutScreen() {
} }
} }
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun ButtonGroup(
onOpenUrl: (String) -> Unit,
onCheckUpdate: () -> Unit
) {
ButtonGroup(
modifier = Modifier.fillMaxWidth(),
overflowIndicator = { menuState ->
ButtonGroupDefaults.OverflowIndicator(menuState = menuState)
},
verticalAlignment = Alignment.CenterVertically
) {
clickableItem(
onClick = { onOpenUrl("https://example.com") },
weight = 1f,
icon = {
Icon(
painter = painterResource(R.drawable.ic_web_outline),
contentDescription = stringResource(R.string.back),
tint = colorScheme.onSurface
)
},
label = ""
)
clickableItem(
onClick = { onOpenUrl("https://github.com/HapeLee/legado-with-MD3") },
weight = 1f,
icon = {
Icon(
painter = painterResource(R.drawable.ic_github),
contentDescription = stringResource(R.string.back),
tint = colorScheme.onSurface
)
},
label = ""
)
clickableItem(
onClick = { onCheckUpdate() },
weight = 1f,
icon = {
Icon(
painter = painterResource(R.drawable.ic_import),
contentDescription = stringResource(R.string.back),
tint = colorScheme.onSurface
)
},
label = ""
)
}
}
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable @Composable
fun AboutScreen( fun AboutScreen(
@@ -148,19 +92,23 @@ fun AboutScreen(
Column( Column(
modifier = Modifier modifier = Modifier
.padding(padding) .padding(padding)
.padding(16.dp) .padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
) { ) {
Image( Image(
painter = painterResource(R.drawable.ic_launcher_foreground), painter = painterResource(R.drawable.ic_launcher_foreground),
contentDescription = "", contentDescription = null,
contentScale = ContentScale.Crop, contentScale = ContentScale.Crop,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .height(120.dp)
.wrapContentWidth(Alignment.CenterHorizontally) .width(160.dp)
.align(Alignment.CenterHorizontally)
) )
Text( Text(
text = stringResource(R.string.app_name), style = MaterialTheme.typography.bodyLarge, text = stringResource(R.string.app_name),
style = MaterialTheme.typography.bodyLarge,
fontSize = 18.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally)) .wrapContentWidth(Alignment.CenterHorizontally))
@@ -172,12 +120,15 @@ fun AboutScreen(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally) .wrapContentWidth(Alignment.CenterHorizontally)
) .padding(vertical = 4.dp))
Text( Text(
text = stringResource(R.string.about_description), style = MaterialTheme.typography.bodyLarge, text = stringResource(R.string.about_description),
style = MaterialTheme.typography.bodyLarge,
fontSize = 12.sp,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally)) .wrapContentWidth(Alignment.CenterHorizontally)
.padding(bottom = 4.dp))
Row (modifier = Modifier Row (modifier = Modifier
.fillMaxWidth(), .fillMaxWidth(),
horizontalArrangement = Arrangement.Center){ horizontalArrangement = Arrangement.Center){
@@ -204,51 +155,58 @@ fun AboutScreen(
} }
SplicedColumnGroup( SplicedColumnGroup(
title = stringResource(R.string.about), title = "",
content = listOf( content = listOf(
{ {
SettingItem( SettingItem(
modifier = Modifier.background(colorScheme.surfaceBright), modifier = Modifier.background(colorScheme.surfaceBright),
title = stringResource(R.string.contributors), title = stringResource(R.string.contributors),
description = "", description = null,
option = null,
onClick = { onClick = {
onOpenUrl("https://github.com/gedoor/legado/graphs/contributors") onOpenUrl("https://github.com/gedoor/legado/graphs/contributors")
} }
) )
SettingItem( SettingItem(
title = stringResource(R.string.privacy_policy), title = stringResource(R.string.privacy_policy),
description = "", description = null,
option = null,
onClick = { onClick = {
onShowMdFile("隐私政策", "privacyPolicy.md") onShowMdFile("隐私政策", "privacyPolicy.md")
} }
) )
SettingItem( SettingItem(
title = stringResource(R.string.license), title = stringResource(R.string.license),
description = "", description = null,
option = null,
onClick = { onClick = {
onShowMdFile("许可证", "LICENSE.md") onShowMdFile("许可证", "LICENSE.md")
} }
) )
SettingItem( SettingItem(
title = stringResource(R.string.disclaimer), title = stringResource(R.string.disclaimer),
description = "", description = null,
option = null,
onClick = { onClick = {
onShowMdFile("免责声明", "disclaimer.md") onShowMdFile("免责声明", "disclaimer.md")
} }
) )
SettingItem( SettingItem(
title = stringResource(R.string.crash_log), title = stringResource(R.string.crash_log),
description = "", description = null,
option = null,
onClick = onShowCrashLogs onClick = onShowCrashLogs
) )
SettingItem( SettingItem(
title = stringResource(R.string.save_log), title = stringResource(R.string.save_log),
description = "", description = null,
option = null,
onClick = onSaveLog onClick = onSaveLog
) )
SettingItem( SettingItem(
title = stringResource(R.string.create_heap_dump), title = stringResource(R.string.create_heap_dump),
description = "", description = null,
option = null,
onClick = onCreateHeapDump onClick = onCreateHeapDump
) )
} }
@@ -7,11 +7,16 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
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.heightIn
import androidx.compose.foundation.layout.padding 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.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.material.icons.filled.Info
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -19,19 +24,82 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.legado.app.base.AppTypography import io.legado.app.base.AppTypography
@Preview(showBackground = true)
@Composable
fun PreviewSettingItemList() {
MaterialTheme {
Column(modifier = Modifier.padding(16.dp)) {
SettingItem(
title = "Only Title",
description = null,
option = null,
onClick = {}
)
SettingItem(
title = "Title + Description",
description = "This is a description",
option = null,
onClick = {}
)
SettingItem(
title = "Title + Option",
description = null,
option = "Dynamic option text",
onClick = {}
)
SettingItem(
title = "Title + Desc + Option",
description = "Description content here",
option = "Animated changing string",
onClick = {}
)
SettingItem(
imageVector = Icons.Default.Info,
title = "With Icon",
description = "Description",
option = "Option",
onClick = {}
)
SettingItem(
title = "With Trailing",
description = "Trailing icon on the right",
option = null,
trailingContent = {
Icon(
imageVector = Icons.Default.ChevronRight,
contentDescription = null
)
},
onClick = {}
)
}
}
}
@Composable @Composable
fun SettingItem( fun SettingItem(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
painter: Painter? = null, painter: Painter? = null,
imageVector: ImageVector? = null,
title: String, title: String,
option: String? = null, option: String? = null,
trailingContent: (@Composable () -> Unit)? = null, trailingContent: @Composable (() -> Unit)? = null,
description: String, description: String? = null,
onClick: () -> Unit onClick: () -> Unit
) { ) {
Row( Row(
@@ -41,9 +109,11 @@ fun SettingItem(
.fillMaxWidth() .fillMaxWidth()
.clickable { onClick() } .clickable { onClick() }
.padding(horizontal = 8.dp) .padding(horizontal = 8.dp)
.padding(vertical = 12.dp), .padding(vertical = 12.dp)
.heightIn(min = 56.dp),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
painter?.let { painter?.let {
Icon( Icon(
modifier = Modifier.padding(end = 8.dp).size(24.dp), modifier = Modifier.padding(end = 8.dp).size(24.dp),
@@ -53,23 +123,42 @@ fun SettingItem(
) )
} }
imageVector?.let {
Icon(
imageVector = it,
contentDescription = null,
modifier = Modifier
.padding(end = 8.dp)
.size(24.dp),
tint = colorScheme.onSurfaceVariant
)
}
Column( Column(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(3.dp) verticalArrangement = if (description == null)
Arrangement.Center
else
Arrangement.spacedBy(3.dp)
) { ) {
Text( Text(
text = title, text = title,
color = colorScheme.onSurface, color = colorScheme.onSurface,
style = AppTypography.titleMedium, style = AppTypography.titleMedium,
fontWeight = FontWeight.Normal fontWeight = FontWeight.Normal
) )
Text(
text = description, description?.let {
color = colorScheme.onSurfaceVariant, Text(
style = AppTypography.labelMedium text = it,
) color = colorScheme.onSurfaceVariant,
style = AppTypography.labelMedium
)
}
option?.let { option?.let {
AnimatedText( AnimatedTextLine(
text = it, text = it,
style = AppTypography.labelMedium, style = AppTypography.labelMedium,
color = colorScheme.primary, color = colorScheme.primary,
@@ -81,7 +170,7 @@ fun SettingItem(
trailingContent?.let { composable -> trailingContent?.let { composable ->
Box( Box(
modifier = Modifier.fillMaxHeight() modifier = Modifier
.width(55.dp), .width(55.dp),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
+1 -3
View File
@@ -96,9 +96,7 @@
<string name="offline_cache_t">离线缓存</string> <string name="offline_cache_t">离线缓存</string>
<string name="offline_cache_s">缓存选择的章节到本地</string> <string name="offline_cache_s">缓存选择的章节到本地</string>
<string name="change_origin">换源</string> <string name="change_origin">换源</string>
<string name="about_description"> <string name="about_description">全新设计的阅读 3.0</string>
全新设计的阅读 3.0
</string>
<string name="app_share_description"> <string name="app_share_description">
阅读 3.0 下载地址:\nhttps://github.com/gedoor/legado/releases 阅读 3.0 下载地址:\nhttps://github.com/gedoor/legado/releases
</string> </string>