From cc61742b5dd598f6e97f81edc9867f53d8e46112 Mon Sep 17 00:00:00 2001 From: HapeLee <1321903405@qq.com> Date: Mon, 5 Jan 2026 01:49:05 +0800 Subject: [PATCH] =?UTF-8?q?[=E4=BC=98=E5=8C=96]=20=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=A4=A7=E5=B8=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/about/AboutScreen.kt | 5 +- .../app/ui/book/bookmark/AllBookmarkScreen.kt | 45 +++++++-- .../app/ui/book/explore/ExploreShowScreen.kt | 9 +- .../ui/book/info/edit/BookInfoEditScreen.kt | 12 +-- .../ui/book/readRecord/ReadRecordScreen.kt | 49 +++++----- .../book/searchContent/SearchContentScreen.kt | 4 +- .../java/io/legado/app/ui/main/my/MyScreen.kt | 7 +- .../app/ui/replace/edit/ReplaceEditScreen.kt | 96 +++++++++++++++---- .../ui/widget/components/SearchBarSection.kt | 63 ++++++++++-- .../app/ui/widget/components/SettingItem.kt | 12 ++- .../main/res/layout/fragment_bookshelf1.xml | 3 +- .../main/res/layout/fragment_bookshelf2.xml | 3 +- .../main/res/layout/fragment_bookshelf3.xml | 3 +- app/src/main/res/layout/fragment_explore.xml | 5 +- app/src/main/res/layout/fragment_rss.xml | 5 +- 15 files changed, 226 insertions(+), 95 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/about/AboutScreen.kt b/app/src/main/java/io/legado/app/ui/about/AboutScreen.kt index ccddb33fe..2f1dd41d0 100644 --- a/app/src/main/java/io/legado/app/ui/about/AboutScreen.kt +++ b/app/src/main/java/io/legado/app/ui/about/AboutScreen.kt @@ -1,7 +1,6 @@ package io.legado.app.ui.about import androidx.compose.foundation.Image -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -21,7 +20,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme.colorScheme -import androidx.compose.material3.MediumTopAppBar +import androidx.compose.material3.MediumFlexibleTopAppBar import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarDefaults @@ -61,7 +60,7 @@ fun AboutScreen( Scaffold( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { - MediumTopAppBar( + MediumFlexibleTopAppBar( title = { Text(stringResource(R.string.about)) }, navigationIcon = { IconButton(onClick = onBack) { diff --git a/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkScreen.kt b/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkScreen.kt index bbc0cdedf..ce66f5b23 100644 --- a/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkScreen.kt @@ -14,7 +14,15 @@ import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.KeyboardArrowDown @@ -22,8 +30,32 @@ import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.UnfoldLess import androidx.compose.material.icons.filled.UnfoldMore -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MediumFlexibleTopAppBar +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.rotate @@ -35,9 +67,9 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import io.legado.app.data.entities.Bookmark import io.legado.app.ui.widget.components.EmptyMessageView +import io.legado.app.ui.widget.components.SearchBarSection import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn import io.legado.app.ui.widget.components.lazylist.Scroller -import io.legado.app.ui.widget.components.SearchBarSection import org.koin.androidx.compose.koinViewModel @OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class, @@ -77,11 +109,10 @@ fun AllBookmarkScreen( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { Column { - MediumTopAppBar( + MediumFlexibleTopAppBar( title = { Text( - text = "所有书签", - style = MaterialTheme.typography.titleLarge + text = "所有书签" ) }, scrollBehavior = scrollBehavior, diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt index f47c89389..14c8a8ae5 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt @@ -56,7 +56,7 @@ import androidx.compose.material3.FilterChip import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MediumTopAppBar +import androidx.compose.material3.MediumFlexibleTopAppBar import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Scaffold @@ -253,7 +253,8 @@ fun ExploreShowScreen( } FlowRow( - modifier = Modifier.fillMaxWidth() + modifier = Modifier + .fillMaxWidth() .padding(16.dp) ) { filteredKinds.forEach { kind -> @@ -393,7 +394,7 @@ fun KindListItem( ) } -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @Composable fun ExploreTopBar( title: String, @@ -408,7 +409,7 @@ fun ExploreTopBar( ) { var showMenu by remember { mutableStateOf(false) } - MediumTopAppBar( + MediumFlexibleTopAppBar( title = { AnimatedTextLine(title, maxLines = 1, overflow = TextOverflow.Ellipsis) }, navigationIcon = { IconButton(onClick = onBack) { diff --git a/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditScreen.kt b/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditScreen.kt index 3204f3cc5..bf9b0ac4b 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditScreen.kt @@ -3,13 +3,11 @@ package io.legado.app.ui.book.info.edit import androidx.activity.compose.rememberLauncherForActivityResult import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState @@ -34,15 +32,11 @@ import androidx.compose.material3.FilledTonalIconButton import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MediumTopAppBar +import androidx.compose.material3.MediumFlexibleTopAppBar import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.OutlinedIconButton import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Scaffold import androidx.compose.material3.Text -import androidx.compose.material3.TextField import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -52,8 +46,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.Modifier.Companion -import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -79,7 +71,7 @@ fun BookInfoEditScreen( Scaffold( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { - MediumTopAppBar( + MediumFlexibleTopAppBar( title = { Text(text = stringResource(id = R.string.book_info_edit)) }, navigationIcon = { IconButton(onClick = onBack) { diff --git a/app/src/main/java/io/legado/app/ui/book/readRecord/ReadRecordScreen.kt b/app/src/main/java/io/legado/app/ui/book/readRecord/ReadRecordScreen.kt index e5e1984b1..74991025f 100644 --- a/app/src/main/java/io/legado/app/ui/book/readRecord/ReadRecordScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/readRecord/ReadRecordScreen.kt @@ -28,10 +28,11 @@ import androidx.compose.material.icons.filled.Timeline import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MediumTopAppBar +import androidx.compose.material3.MediumFlexibleTopAppBar import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -70,13 +71,8 @@ import org.koin.androidx.compose.koinViewModel import java.time.LocalDate import java.time.format.DateTimeFormatter import java.util.Date -import kotlin.collections.component1 -import kotlin.collections.component2 -import kotlin.collections.isNotEmpty -import kotlin.collections.map -import kotlin.collections.sumOf -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @Composable fun ReadRecordScreen( viewModel: ReadRecordViewModel = koinViewModel(), @@ -98,7 +94,7 @@ fun ReadRecordScreen( } LaunchedEffect(searchText) { - if (showSearch) { + if (showSearch && searchText.isNotBlank()) { delay(100L) viewModel.loadData(searchText) } @@ -108,24 +104,21 @@ fun ReadRecordScreen( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { Column { - MediumTopAppBar( + MediumFlexibleTopAppBar( title = { - val (mainTitle, subTitle) = when (displayMode) { - DisplayMode.AGGREGATE -> "阅读记录" to "汇总视图" - DisplayMode.TIMELINE -> "阅读记录" to "时间线视图" - DisplayMode.LATEST -> "阅读记录" to "最后阅读" - } - Column { - Text( - text = mainTitle, - style = MaterialTheme.typography.titleLarge, - ) - - AnimatedTextLine( - text = subTitle, - style = MaterialTheme.typography.titleMedium - ) + Text( + text = "阅读记录" + ) + }, + subtitle = { + val subTitle = when (displayMode) { + DisplayMode.AGGREGATE -> "汇总视图" + DisplayMode.TIMELINE -> "时间线视图" + DisplayMode.LATEST -> "最后阅读" } + AnimatedTextLine( + text = subTitle + ) }, navigationIcon = { IconButton(onClick = onBackClick) { @@ -170,18 +163,20 @@ fun ReadRecordScreen( selectedDate = state.selectedDate, onDateSelected = { date -> viewModel.setSelectedDate(date) - showCalendar = false // 选择后自动收起日历 + showCalendar = false }, onClearDate = { viewModel.setSelectedDate(null) - showCalendar = false // 清除后自动收起 + showCalendar = false } ) } } } ) { padding -> - Column(modifier = Modifier.padding(padding).fillMaxSize()) { + Column(modifier = Modifier + .padding(padding) + .fillMaxSize()) { val contentState = when { state.isLoading -> "LOADING" (displayMode == DisplayMode.AGGREGATE && state.groupedRecords.isEmpty()) || diff --git a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentScreen.kt b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentScreen.kt index 890907884..b046a31cb 100644 --- a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentScreen.kt @@ -31,7 +31,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MediumTopAppBar +import androidx.compose.material3.MediumFlexibleTopAppBar import androidx.compose.material3.PlainTooltip import androidx.compose.material3.Scaffold import androidx.compose.material3.Text @@ -126,7 +126,7 @@ fun SearchContentScreen( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { Column { - MediumTopAppBar( + MediumFlexibleTopAppBar( title = { val title = if (searchQuery.isNotBlank() && searchResults.isNotEmpty()) { "共 ${searchResults.size} 条结果" diff --git a/app/src/main/java/io/legado/app/ui/main/my/MyScreen.kt b/app/src/main/java/io/legado/app/ui/main/my/MyScreen.kt index ceaed6f46..55b911cee 100644 --- a/app/src/main/java/io/legado/app/ui/main/my/MyScreen.kt +++ b/app/src/main/java/io/legado/app/ui/main/my/MyScreen.kt @@ -26,9 +26,10 @@ import androidx.compose.material.icons.filled.Translate import androidx.compose.material.icons.filled.Web import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.MediumTopAppBar +import androidx.compose.material3.MediumFlexibleTopAppBar import androidx.compose.material3.Scaffold import androidx.compose.material3.Switch import androidx.compose.material3.Text @@ -55,7 +56,7 @@ import io.legado.app.ui.widget.components.SettingItem import io.legado.app.ui.widget.components.SplicedColumnGroup -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @Composable fun MyScreen( viewModel: MyViewModel, @@ -70,7 +71,7 @@ fun MyScreen( contentWindowInsets = WindowInsets.systemBars .only(WindowInsetsSides.Horizontal + WindowInsetsSides.Top), topBar = { - MediumTopAppBar( + MediumFlexibleTopAppBar( title = { Text( text = stringResource(R.string.my) diff --git a/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditScreen.kt b/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditScreen.kt index 1b19ed42f..7cd062ab0 100644 --- a/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditScreen.kt +++ b/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditScreen.kt @@ -6,16 +6,63 @@ import androidx.compose.animation.slideOutVertically import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.horizontalScroll -import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.ime +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.HelpOutline -import androidx.compose.material.icons.filled.* -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.icons.filled.Save +import androidx.compose.material.icons.filled.Settings +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.AssistChip +import androidx.compose.material3.BottomAppBar +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Checkbox +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi +import androidx.compose.material3.ExposedDropdownMenuAnchorType +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults +import androidx.compose.material3.FilterChip +import androidx.compose.material3.FilterChipDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MediumFlexibleTopAppBar +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateMapOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -32,7 +79,7 @@ fun keyboardAsState(): State { return rememberUpdatedState(isImeVisible) } -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @Composable fun ReplaceEditScreen( onBack: () -> Unit, @@ -48,7 +95,7 @@ fun ReplaceEditScreen( Scaffold( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { - MediumTopAppBar( + MediumFlexibleTopAppBar( title = { Text(if (state.id > 0) "编辑替换规则" else "新增替换规则") }, navigationIcon = { IconButton(onClick = onBack) { Icon(Icons.AutoMirrored.Filled.ArrowBack, "Back") } @@ -111,7 +158,10 @@ fun ReplaceEditScreen( label = { Text("规则名称") }, modifier = Modifier .fillMaxWidth() - .onFocusChanged { if (it.isFocused) viewModel.activeField = ReplaceEditViewModel.ActiveField.Name }, + .onFocusChanged { + if (it.isFocused) viewModel.activeField = + ReplaceEditViewModel.ActiveField.Name + }, singleLine = true ) @@ -129,7 +179,10 @@ fun ReplaceEditScreen( placeholder = { Text("输入正则表达式或关键字") }, modifier = Modifier .fillMaxWidth() - .onFocusChanged { if (it.isFocused) viewModel.activeField = ReplaceEditViewModel.ActiveField.Pattern } + .onFocusChanged { + if (it.isFocused) viewModel.activeField = + ReplaceEditViewModel.ActiveField.Pattern + } ) OutlinedTextField( @@ -139,7 +192,10 @@ fun ReplaceEditScreen( placeholder = { Text("输入替换内容或捕获组") }, modifier = Modifier .fillMaxWidth() - .onFocusChanged { if (it.isFocused) viewModel.activeField = ReplaceEditViewModel.ActiveField.Replacement } + .onFocusChanged { + if (it.isFocused) viewModel.activeField = + ReplaceEditViewModel.ActiveField.Replacement + } ) Row( @@ -187,7 +243,10 @@ fun ReplaceEditScreen( placeholder = { Text("指定规则适用的范围") }, modifier = Modifier .fillMaxWidth() - .onFocusChanged { if (it.isFocused) viewModel.activeField = ReplaceEditViewModel.ActiveField.Scope } + .onFocusChanged { + if (it.isFocused) viewModel.activeField = + ReplaceEditViewModel.ActiveField.Scope + } ) OutlinedTextField( @@ -197,7 +256,10 @@ fun ReplaceEditScreen( placeholder = { Text("指定规则不适用的范围") }, modifier = Modifier .fillMaxWidth() - .onFocusChanged { if (it.isFocused) viewModel.activeField = ReplaceEditViewModel.ActiveField.Exclude } + .onFocusChanged { + if (it.isFocused) viewModel.activeField = + ReplaceEditViewModel.ActiveField.Exclude + } ) OutlinedTextField( @@ -261,13 +323,15 @@ fun GroupSelector( value = currentGroup, onValueChange = onGroupChange, label = { Text("分组") }, - placeholder = {Text("默认")}, + placeholder = { Text("默认") }, trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }, colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(), - modifier = Modifier.fillMaxWidth().menuAnchor( - ExposedDropdownMenuAnchorType.PrimaryEditable, - true - ) + modifier = Modifier + .fillMaxWidth() + .menuAnchor( + ExposedDropdownMenuAnchorType.PrimaryEditable, + true + ) ) ExposedDropdownMenu( expanded = expanded, diff --git a/app/src/main/java/io/legado/app/ui/widget/components/SearchBarSection.kt b/app/src/main/java/io/legado/app/ui/widget/components/SearchBarSection.kt index c45a1ffaa..e91a3716f 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/SearchBarSection.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/SearchBarSection.kt @@ -1,11 +1,19 @@ package io.legado.app.ui.widget.components +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.scaleIn +import androidx.compose.animation.scaleOut +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Clear import androidx.compose.material.icons.filled.Search +import androidx.compose.material3.DropdownMenu import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -15,6 +23,11 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp @@ -25,8 +38,14 @@ fun SearchBarSection( query: String, onQueryChange: (String) -> Unit, placeholder: String = "搜索书名", - backgroundColor: Color = MaterialTheme.colorScheme.surfaceContainerLow + backgroundColor: Color = MaterialTheme.colorScheme.surfaceContainerLow, + //外部定义末尾的图标按钮 + trailingIcon: @Composable (() -> Unit)? = null, + //外部定义下拉菜单的内容 + dropdownMenu: (@Composable (onDismiss: () -> Unit) -> Unit)? = null ) { + var showMenu by remember { mutableStateOf(false) } + Surface( modifier = Modifier .fillMaxWidth() @@ -35,17 +54,47 @@ fun SearchBarSection( color = backgroundColor ) { TextField( + value = query, + onValueChange = onQueryChange, modifier = Modifier .fillMaxWidth() .padding(horizontal = 4.dp), - value = query, - onValueChange = onQueryChange, placeholder = { Text(placeholder) }, leadingIcon = { Icon(Icons.Default.Search, null) }, trailingIcon = { - if (query.isNotEmpty()) { - IconButton(onClick = { onQueryChange("") }) { - Icon(Icons.Default.Clear, null) + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(end = 4.dp) + ) { + AnimatedVisibility( + visible = query.isNotEmpty(), + enter = fadeIn() + scaleIn(initialScale = 0.8f), + exit = fadeOut() + scaleOut(targetScale = 0.8f) + ) { + IconButton(onClick = { + onQueryChange("") + }) { + Icon(Icons.Default.Clear, "清空输入") + } + } + + if (trailingIcon != null) { + Box { + IconButton(onClick = { + if (dropdownMenu != null) showMenu = true + }) { + trailingIcon() + } + + if (dropdownMenu != null) { + DropdownMenu( + expanded = showMenu, + onDismissRequest = { showMenu = false } + ) { + dropdownMenu { showMenu = false } + } + } + } } } }, @@ -59,4 +108,4 @@ fun SearchBarSection( ) ) } -} +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/widget/components/SettingItem.kt b/app/src/main/java/io/legado/app/ui/widget/components/SettingItem.kt index 7288a9335..0563019f4 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/SettingItem.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/SettingItem.kt @@ -1,8 +1,8 @@ package io.legado.app.ui.widget.components +import androidx.compose.animation.animateContentSize import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -10,6 +10,7 @@ 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.Card import androidx.compose.material3.DropdownMenu import androidx.compose.material3.Icon import androidx.compose.material3.ListItem @@ -22,7 +23,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.style.TextOverflow @@ -103,10 +103,14 @@ fun SettingItem( ) { var showMenu by remember { mutableStateOf(false) } - Box ( modifier = Modifier.fillMaxWidth() ){ + Card( + modifier = Modifier + .fillMaxWidth() + .animateContentSize(), + shape = RoundedCornerShape(8.dp) + ) { ListItem( modifier = modifier - .clip(RoundedCornerShape(4.dp)) .combinedClickable( onClick = onClick, onLongClick = { diff --git a/app/src/main/res/layout/fragment_bookshelf1.xml b/app/src/main/res/layout/fragment_bookshelf1.xml index 5ddc1a191..929c4d176 100644 --- a/app/src/main/res/layout/fragment_bookshelf1.xml +++ b/app/src/main/res/layout/fragment_bookshelf1.xml @@ -19,8 +19,7 @@ android:layout_width="match_parent" android:layout_height="?attr/collapsingToolbarLayoutMediumSize" style="?attr/collapsingToolbarLayoutMediumStyle" - app:collapsedTitleTextAppearance="?attr/textAppearanceTitleLarge" - app:expandedTitleTextAppearance="?attr/textAppearanceHeadlineLarge" + app:expandedTitleTextAppearance="?attr/textAppearanceHeadlineMedium" app:titleCollapseMode="scale" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"> diff --git a/app/src/main/res/layout/fragment_bookshelf2.xml b/app/src/main/res/layout/fragment_bookshelf2.xml index 32a4c539a..c7ee12aa0 100644 --- a/app/src/main/res/layout/fragment_bookshelf2.xml +++ b/app/src/main/res/layout/fragment_bookshelf2.xml @@ -18,8 +18,7 @@ style="?attr/collapsingToolbarLayoutMediumStyle" android:layout_width="match_parent" android:layout_height="?attr/collapsingToolbarLayoutMediumSize" - app:collapsedTitleTextAppearance="?attr/textAppearanceTitleLarge" - app:expandedTitleTextAppearance="?attr/textAppearanceHeadlineLarge" + app:expandedTitleTextAppearance="?attr/textAppearanceHeadlineMedium" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" app:titleCollapseMode="scale"> diff --git a/app/src/main/res/layout/fragment_bookshelf3.xml b/app/src/main/res/layout/fragment_bookshelf3.xml index 7e69fcff0..f210d36f6 100644 --- a/app/src/main/res/layout/fragment_bookshelf3.xml +++ b/app/src/main/res/layout/fragment_bookshelf3.xml @@ -19,8 +19,7 @@ android:layout_width="match_parent" android:layout_height="?attr/collapsingToolbarLayoutMediumSize" style="?attr/collapsingToolbarLayoutLargeStyle" - app:collapsedTitleTextAppearance="?attr/textAppearanceTitleLarge" - app:expandedTitleTextAppearance="?attr/textAppearanceHeadlineLarge" + app:expandedTitleTextAppearance="?attr/textAppearanceHeadlineMedium" app:titleCollapseMode="scale" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"> diff --git a/app/src/main/res/layout/fragment_explore.xml b/app/src/main/res/layout/fragment_explore.xml index d6f3ded8e..49533e465 100644 --- a/app/src/main/res/layout/fragment_explore.xml +++ b/app/src/main/res/layout/fragment_explore.xml @@ -17,10 +17,9 @@