[优化] 优化了一些界面布局
This commit is contained in:
9 files changed
+149
-201
No files matched your search
@@ -45,6 +45,7 @@ abstract class BaseComposeActivity(
|
|||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
setupSystemBar()
|
||||||
// Compose 入口
|
// Compose 入口
|
||||||
setContent {
|
setContent {
|
||||||
AppTheme {
|
AppTheme {
|
||||||
@@ -54,8 +55,6 @@ abstract class BaseComposeActivity(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setupSystemBar()
|
|
||||||
|
|
||||||
if (imageBg) {
|
if (imageBg) {
|
||||||
upBackgroundImage()
|
upBackgroundImage()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ class AboutActivity : BaseComposeActivity() {
|
|||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
AboutScreen(
|
AboutScreen(
|
||||||
|
onBack = { finish() },
|
||||||
onCheckUpdate = { checkUpdate() },
|
onCheckUpdate = { checkUpdate() },
|
||||||
onOpenUrl = { openUrl(it) },
|
onOpenUrl = { openUrl(it) },
|
||||||
onShowMdFile = { title, file -> showMdFile(title, file) },
|
onShowMdFile = { title, file -> showMdFile(title, file) },
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package io.legado.app.ui.about
|
package io.legado.app.ui.about
|
||||||
|
|
||||||
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.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@@ -25,7 +24,6 @@ import androidx.compose.material3.MaterialTheme.colorScheme
|
|||||||
import androidx.compose.material3.MediumTopAppBar
|
import androidx.compose.material3.MediumTopAppBar
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
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
|
||||||
@@ -36,11 +34,9 @@ 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.text.font.FontWeight
|
||||||
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 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.constant.AppConst.appInfo
|
import io.legado.app.constant.AppConst.appInfo
|
||||||
import io.legado.app.ui.widget.components.SettingItem
|
import io.legado.app.ui.widget.components.SettingItem
|
||||||
import io.legado.app.ui.widget.components.SplicedColumnGroup
|
import io.legado.app.ui.widget.components.SplicedColumnGroup
|
||||||
@@ -50,7 +46,7 @@ import io.legado.app.ui.widget.components.TextCard
|
|||||||
@Composable
|
@Composable
|
||||||
fun AboutScreen(
|
fun AboutScreen(
|
||||||
versionName: String = appInfo.versionName,
|
versionName: String = appInfo.versionName,
|
||||||
onNavigateBack: () -> Unit = {},
|
onBack: () -> Unit = {},
|
||||||
onCheckUpdate: () -> Unit = {},
|
onCheckUpdate: () -> Unit = {},
|
||||||
onOpenUrl: (String) -> Unit = {},
|
onOpenUrl: (String) -> Unit = {},
|
||||||
onShowMdFile: (String, String) -> Unit = { _, _ -> },
|
onShowMdFile: (String, String) -> Unit = { _, _ -> },
|
||||||
@@ -68,7 +64,7 @@ fun AboutScreen(
|
|||||||
MediumTopAppBar(
|
MediumTopAppBar(
|
||||||
title = { Text(stringResource(R.string.about)) },
|
title = { Text(stringResource(R.string.about)) },
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = onNavigateBack) {
|
IconButton(onClick = onBack) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
contentDescription = stringResource(R.string.back)
|
contentDescription = stringResource(R.string.back)
|
||||||
@@ -82,7 +78,6 @@ fun AboutScreen(
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(padding)
|
.padding(padding)
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
@@ -145,63 +140,60 @@ fun AboutScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
SplicedColumnGroup(
|
SplicedColumnGroup(
|
||||||
title = "",
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
content = listOf(
|
title = ""
|
||||||
{
|
){
|
||||||
SettingItem(
|
SettingItem(
|
||||||
modifier = Modifier.background(colorScheme.surfaceBright),
|
title = stringResource(R.string.contributors),
|
||||||
title = stringResource(R.string.contributors),
|
description = null,
|
||||||
description = null,
|
option = null,
|
||||||
option = null,
|
onClick = {
|
||||||
onClick = {
|
onOpenUrl("https://github.com/gedoor/legado/graphs/contributors")
|
||||||
onOpenUrl("https://github.com/gedoor/legado/graphs/contributors")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
SettingItem(
|
|
||||||
title = stringResource(R.string.privacy_policy),
|
|
||||||
description = null,
|
|
||||||
option = null,
|
|
||||||
onClick = {
|
|
||||||
onShowMdFile("隐私政策", "privacyPolicy.md")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
SettingItem(
|
|
||||||
title = stringResource(R.string.license),
|
|
||||||
description = null,
|
|
||||||
option = null,
|
|
||||||
onClick = {
|
|
||||||
onShowMdFile("许可证", "LICENSE.md")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
SettingItem(
|
|
||||||
title = stringResource(R.string.disclaimer),
|
|
||||||
description = null,
|
|
||||||
option = null,
|
|
||||||
onClick = {
|
|
||||||
onShowMdFile("免责声明", "disclaimer.md")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
SettingItem(
|
|
||||||
title = stringResource(R.string.crash_log),
|
|
||||||
description = null,
|
|
||||||
option = null,
|
|
||||||
onClick = onShowCrashLogs
|
|
||||||
)
|
|
||||||
SettingItem(
|
|
||||||
title = stringResource(R.string.save_log),
|
|
||||||
description = null,
|
|
||||||
option = null,
|
|
||||||
onClick = onSaveLog
|
|
||||||
)
|
|
||||||
SettingItem(
|
|
||||||
title = stringResource(R.string.create_heap_dump),
|
|
||||||
description = null,
|
|
||||||
option = null,
|
|
||||||
onClick = onCreateHeapDump
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
SettingItem(
|
||||||
|
title = stringResource(R.string.privacy_policy),
|
||||||
|
description = null,
|
||||||
|
option = null,
|
||||||
|
onClick = {
|
||||||
|
onShowMdFile("隐私政策", "privacyPolicy.md")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
SettingItem(
|
||||||
|
title = stringResource(R.string.license),
|
||||||
|
description = null,
|
||||||
|
option = null,
|
||||||
|
onClick = {
|
||||||
|
onShowMdFile("许可证", "LICENSE.md")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
SettingItem(
|
||||||
|
title = stringResource(R.string.disclaimer),
|
||||||
|
description = null,
|
||||||
|
option = null,
|
||||||
|
onClick = {
|
||||||
|
onShowMdFile("免责声明", "disclaimer.md")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
SettingItem(
|
||||||
|
title = stringResource(R.string.crash_log),
|
||||||
|
description = null,
|
||||||
|
option = null,
|
||||||
|
onClick = onShowCrashLogs
|
||||||
|
)
|
||||||
|
SettingItem(
|
||||||
|
title = stringResource(R.string.save_log),
|
||||||
|
description = null,
|
||||||
|
option = null,
|
||||||
|
onClick = onSaveLog
|
||||||
|
)
|
||||||
|
SettingItem(
|
||||||
|
title = stringResource(R.string.create_heap_dump),
|
||||||
|
description = null,
|
||||||
|
option = null,
|
||||||
|
onClick = onCreateHeapDump
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package io.legado.app.ui.book.readRecord
|
package io.legado.app.ui.book.readRecord
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.compose.material3.*
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import io.legado.app.base.AppTheme
|
||||||
import io.legado.app.data.appDb
|
import io.legado.app.data.appDb
|
||||||
import io.legado.app.utils.startActivityForBook
|
import io.legado.app.utils.startActivityForBook
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -22,10 +22,8 @@ class ReadRecordActivity : BaseComposeActivity() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
MaterialTheme {
|
AppTheme {
|
||||||
val viewModel: ReadRecordViewModel = koinViewModel()
|
|
||||||
ReadRecordScreen(
|
ReadRecordScreen(
|
||||||
viewModel = viewModel,
|
|
||||||
onBackClick = { finish() },
|
onBackClick = { finish() },
|
||||||
onBookClick = { bookName ->
|
onBookClick = { bookName ->
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ import io.legado.app.ui.widget.components.SearchBarSection
|
|||||||
import io.legado.app.ui.widget.components.SectionHeader
|
import io.legado.app.ui.widget.components.SectionHeader
|
||||||
import io.legado.app.utils.StringUtils.formatFriendlyDate
|
import io.legado.app.utils.StringUtils.formatFriendlyDate
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
import org.koin.androidx.compose.koinViewModel
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@@ -78,7 +79,7 @@ import kotlin.collections.sumOf
|
|||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ReadRecordScreen(
|
fun ReadRecordScreen(
|
||||||
viewModel: ReadRecordViewModel,
|
viewModel: ReadRecordViewModel = koinViewModel(),
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
onBookClick: (String) -> Unit
|
onBookClick: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -3,17 +3,21 @@ package io.legado.app.ui.replace
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
import io.legado.app.base.AppTheme
|
import io.legado.app.base.AppTheme
|
||||||
|
import io.legado.app.base.BaseComposeActivity
|
||||||
|
|
||||||
class ReplaceRuleActivity : AppCompatActivity() {
|
class ReplaceRuleActivity : BaseComposeActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
@Composable
|
||||||
super.onCreate(savedInstanceState)
|
override fun Content() {
|
||||||
setContent {
|
AppTheme {
|
||||||
AppTheme {
|
ReplaceRuleScreen(onBackClick = { finish() })
|
||||||
ReplaceRuleScreen(onBackClick = { finish() })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -330,15 +330,15 @@ fun ReplaceRuleScreen(
|
|||||||
snackbarHost = { SnackbarHost(snackbarHostState) },
|
snackbarHost = { SnackbarHost(snackbarHostState) },
|
||||||
topBar = {
|
topBar = {
|
||||||
Column {
|
Column {
|
||||||
val titleText = remember(isUploading, inSelectionMode, selectedRuleIds.size, rules.size) {
|
|
||||||
when {
|
|
||||||
isUploading -> "正在上传..."
|
|
||||||
inSelectionMode -> "已选择 ${selectedRuleIds.size}/${rules.size}"
|
|
||||||
else -> "替换规则"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MediumTopAppBar(
|
MediumTopAppBar(
|
||||||
title = {
|
title = {
|
||||||
|
val titleText = remember(isUploading, inSelectionMode, selectedRuleIds.size, rules.size) {
|
||||||
|
when {
|
||||||
|
isUploading -> "正在上传..."
|
||||||
|
inSelectionMode -> "已选择 ${selectedRuleIds.size}/${rules.size}"
|
||||||
|
else -> "替换规则"
|
||||||
|
}
|
||||||
|
}
|
||||||
AnimatedText(
|
AnimatedText(
|
||||||
text = titleText
|
text = titleText
|
||||||
)
|
)
|
||||||
@@ -485,12 +485,12 @@ fun ReplaceRuleScreen(
|
|||||||
) { padding ->
|
) { padding ->
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.padding(padding)
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
FastScrollLazyColumn(
|
FastScrollLazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(padding)
|
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
contentPadding = PaddingValues(
|
contentPadding = PaddingValues(
|
||||||
top = 8.dp,
|
top = 8.dp,
|
||||||
@@ -561,7 +561,6 @@ fun ReplaceRuleScreen(
|
|||||||
onSelectionChange = viewModel::setSelection,
|
onSelectionChange = viewModel::setSelection,
|
||||||
haptic = haptic,
|
haptic = haptic,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(padding)
|
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.width(60.dp)
|
.width(60.dp)
|
||||||
.align(Alignment.TopStart)
|
.align(Alignment.TopStart)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.legado.app.ui.widget.components
|
package io.legado.app.ui.widget.components
|
||||||
|
|
||||||
|
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
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -15,6 +16,8 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.filled.ChevronRight
|
import androidx.compose.material.icons.filled.ChevronRight
|
||||||
import androidx.compose.material.icons.filled.Info
|
import androidx.compose.material.icons.filled.Info
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.ListItem
|
||||||
|
import androidx.compose.material3.ListItemDefaults
|
||||||
import androidx.compose.material3.MaterialTheme
|
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
|
||||||
@@ -95,85 +98,64 @@ fun SettingItem(
|
|||||||
painter: Painter? = null,
|
painter: Painter? = null,
|
||||||
imageVector: ImageVector? = null,
|
imageVector: ImageVector? = null,
|
||||||
title: String,
|
title: String,
|
||||||
|
description: String? = null,
|
||||||
option: String? = null,
|
option: String? = null,
|
||||||
trailingContent: @Composable (() -> Unit)? = null,
|
trailingContent: @Composable (() -> Unit)? = null,
|
||||||
description: String? = null,
|
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
Row(
|
ListItem(
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.clip(RoundedCornerShape(4.dp))
|
.clip(RoundedCornerShape(4.dp))
|
||||||
.then(modifier)
|
.clickable(onClick = onClick),
|
||||||
.fillMaxWidth()
|
leadingContent = {
|
||||||
.clickable { onClick() }
|
when {
|
||||||
.padding(horizontal = 8.dp)
|
painter != null -> {
|
||||||
.padding(vertical = 12.dp)
|
Icon(
|
||||||
.heightIn(min = 56.dp),
|
painter = painter,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
contentDescription = null,
|
||||||
) {
|
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
painter?.let {
|
}
|
||||||
Icon(
|
|
||||||
modifier = Modifier.padding(end = 8.dp).size(24.dp),
|
|
||||||
painter = it,
|
|
||||||
tint = colorScheme.onSurfaceVariant,
|
|
||||||
contentDescription = "Icon"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
imageVector?.let {
|
|
||||||
Icon(
|
|
||||||
imageVector = it,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(end = 8.dp)
|
|
||||||
.size(24.dp),
|
|
||||||
tint = colorScheme.onSurfaceVariant
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
verticalArrangement = if (description == null)
|
|
||||||
Arrangement.Center
|
|
||||||
else
|
|
||||||
Arrangement.spacedBy(3.dp)
|
|
||||||
) {
|
|
||||||
|
|
||||||
|
imageVector != null -> {
|
||||||
|
Icon(
|
||||||
|
imageVector = imageVector,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = title,
|
||||||
color = colorScheme.onSurface,
|
style = MaterialTheme.typography.titleMedium
|
||||||
style = AppTypography.titleMedium,
|
|
||||||
fontWeight = FontWeight.Normal
|
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
supportingContent = {
|
||||||
|
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
|
||||||
|
description?.let {
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
description?.let {
|
option?.let {
|
||||||
Text(
|
AnimatedTextLine(
|
||||||
text = it,
|
text = it,
|
||||||
color = colorScheme.onSurfaceVariant,
|
style = MaterialTheme.typography.labelMedium,
|
||||||
style = AppTypography.labelMedium
|
color = MaterialTheme.colorScheme.primary,
|
||||||
)
|
maxLines = 3,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
option?.let {
|
trailingContent = trailingContent,
|
||||||
AnimatedTextLine(
|
colors = ListItemDefaults.colors(
|
||||||
text = it,
|
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||||
style = AppTypography.labelMedium,
|
)
|
||||||
color = colorScheme.primary,
|
)
|
||||||
maxLines = 3,
|
|
||||||
overflow = TextOverflow.Ellipsis
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trailingContent?.let { composable ->
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.width(55.dp),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
composable()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,12 @@ package io.legado.app.ui.widget.components
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
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.ColumnScope
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.CardDefaults
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -14,7 +18,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings Group Container by https://github.com/wxxsfxyzm/InstallerX-Revived
|
* Settings Group Container by https://github.com/wxxsfxyzm/InstallerX-Revived
|
||||||
*
|
* Edit by @Kudomaga
|
||||||
* @param title the title of the group
|
* @param title the title of the group
|
||||||
* @param content a list of composable that will be displayed in the group
|
* @param content a list of composable that will be displayed in the group
|
||||||
* @param modifier Modifier
|
* @param modifier Modifier
|
||||||
@@ -23,61 +27,29 @@ import androidx.compose.ui.unit.dp
|
|||||||
fun SplicedColumnGroup(
|
fun SplicedColumnGroup(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
title: String = "",
|
title: String = "",
|
||||||
content: List<@Composable () -> Unit>,
|
content: @Composable ColumnScope.() -> Unit,
|
||||||
) {
|
) {
|
||||||
if (content.isEmpty()) return
|
|
||||||
|
|
||||||
val cornerRadius = 16.dp
|
|
||||||
val connectionRadius = 5.dp
|
|
||||||
// Define shapes for different positions.
|
|
||||||
val topShape = RoundedCornerShape(
|
|
||||||
topStart = cornerRadius,
|
|
||||||
topEnd = cornerRadius,
|
|
||||||
bottomStart = connectionRadius,
|
|
||||||
bottomEnd = connectionRadius
|
|
||||||
)
|
|
||||||
val middleShape = RoundedCornerShape(connectionRadius)
|
|
||||||
val bottomShape = RoundedCornerShape(
|
|
||||||
topStart = connectionRadius,
|
|
||||||
topEnd = connectionRadius,
|
|
||||||
bottomStart = cornerRadius,
|
|
||||||
bottomEnd = cornerRadius
|
|
||||||
)
|
|
||||||
val singleShape = RoundedCornerShape(cornerRadius)
|
|
||||||
|
|
||||||
Column(modifier = modifier.padding(vertical = 8.dp)) {
|
Column(modifier = modifier.padding(vertical = 8.dp)) {
|
||||||
// Group title
|
if (title.isNotEmpty()) {
|
||||||
if (title != "")
|
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = title,
|
||||||
style = MaterialTheme.typography.titleSmall,
|
style = MaterialTheme.typography.labelLarge,
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
modifier = Modifier.padding(start = 16.dp, bottom = 8.dp)
|
modifier = Modifier.padding(start = 16.dp, bottom = 8.dp)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// The container for setting items.
|
Card(
|
||||||
Column(
|
shape = RoundedCornerShape(16.dp),
|
||||||
modifier = Modifier.clip(
|
colors = CardDefaults.cardColors(
|
||||||
// Clip the whole column to ensure content stays within the rounded bounds.
|
containerColor = MaterialTheme.colorScheme.surface
|
||||||
if (content.size == 1) singleShape else RoundedCornerShape(cornerRadius)
|
|
||||||
),
|
),
|
||||||
verticalArrangement = Arrangement.spacedBy(2.dp)
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
content.forEachIndexed { index, itemContent ->
|
Column(
|
||||||
// Determine the shape based on the pkg's position.
|
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
val shape = when {
|
) {
|
||||||
content.size == 1 -> singleShape
|
content()
|
||||||
index == 0 -> topShape
|
|
||||||
index == content.size - 1 -> bottomShape
|
|
||||||
else -> middleShape
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply background with the correct shape to the pkg.
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.background(MaterialTheme.colorScheme.surfaceBright, shape)
|
|
||||||
) {
|
|
||||||
itemContent()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user