fix(ui): clear article title selection on any tap

The title SelectionContainer covered only the text, so a tap on the empty bar area or the article body never cleared the highlight. A tap anywhere on the article screen now recreates the container and drops the selection.
This commit is contained in:
OneWay committed 2026-09-24 10:00:00 +08:00
1 parent 98ec38f272
commit e4e50db08e
2 files changed
+48 -27

No files matched your search

@@ -1,6 +1,7 @@
package com.example.research.ui.article package com.example.research.ui.article
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
@@ -276,6 +277,7 @@ fun ArticleTitleBar(
onNavigateBack: () -> Unit, onNavigateBack: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
compact: Boolean = false, compact: Boolean = false,
selectionReset: Int = 0,
) { ) {
val title = when (articleState) { val title = when (articleState) {
is ArticleState.Loading -> articleState.title is ArticleState.Loading -> articleState.title
@@ -321,18 +323,20 @@ fun ArticleTitleBar(
} }
} }
SelectionContainer { key(selectionReset) {
Text( SelectionContainer {
text = title, Text(
style = MaterialTheme.typography.dictionaryTitleLarge, text = title,
color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.dictionaryTitleLarge,
maxLines = 1, color = MaterialTheme.colorScheme.onSurface,
overflow = TextOverflow.Ellipsis, maxLines = 1,
modifier = Modifier overflow = TextOverflow.Ellipsis,
.padding(start = if (showBackButton) Spacing.searchTextStart - Spacing.iconStart - 24.dp else 16.dp) modifier = Modifier
.testTag("article_title") .padding(start = if (showBackButton) Spacing.searchTextStart - Spacing.iconStart - 24.dp else 16.dp)
.semantics { testTagsAsResourceId = true } .testTag("article_title")
) .semantics { testTagsAsResourceId = true }
)
}
} }
} }
} }
@@ -346,22 +350,31 @@ internal fun ArticleScreen(
onRefClick: ((String) -> Unit)? = null, onRefClick: ((String) -> Unit)? = null,
onScrollPositionChanged: ((Int, Int) -> Unit)? = null, onScrollPositionChanged: ((Int, Int) -> Unit)? = null,
) { ) {
Scaffold( val titleSelectionReset = remember { mutableIntStateOf(0) }
topBar = { Box(
ArticleTitleBar( modifier = Modifier.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null
) { titleSelectionReset.intValue++ }
) {
Scaffold(
topBar = {
ArticleTitleBar(
articleState = articleState,
showBackButton = true,
onNavigateBack = onNavigateBack,
selectionReset = titleSelectionReset.intValue
)
},
contentWindowInsets = AppWindowInsets.contentWithNavigation
) { padding ->
ArticleContent(
articleState = articleState, articleState = articleState,
showBackButton = true, onNavigateBack = onNavigateBack,
onNavigateBack = onNavigateBack onRefClick = onRefClick,
onScrollPositionChanged = onScrollPositionChanged,
modifier = Modifier.padding(padding)
) )
}, }
contentWindowInsets = AppWindowInsets.contentWithNavigation
) { padding ->
ArticleContent(
articleState = articleState,
onNavigateBack = onNavigateBack,
onRefClick = onRefClick,
onScrollPositionChanged = onScrollPositionChanged,
modifier = Modifier.padding(padding)
)
} }
} }
@@ -1,5 +1,7 @@
package com.example.research.ui.main package com.example.research.ui.main
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -90,9 +92,14 @@ fun AdaptiveMainScreen(
) )
}, },
detailPane = { detailPane = {
val titleSelectionReset = remember { mutableIntStateOf(0) }
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null
) { titleSelectionReset.intValue++ }
.padding(bottom = 16.dp) .padding(bottom = 16.dp)
) { ) {
ArticleTitleBar( ArticleTitleBar(
@@ -100,6 +107,7 @@ fun AdaptiveMainScreen(
showBackButton = isShowingDetail && articleState != null, showBackButton = isShowingDetail && articleState != null,
onNavigateBack = onNavigateBackFromArticle, onNavigateBack = onNavigateBackFromArticle,
compact = true, compact = true,
selectionReset = titleSelectionReset.intValue,
modifier = Modifier.windowInsetsPadding( modifier = Modifier.windowInsetsPadding(
WindowInsets.safeDrawing.only(WindowInsetsSides.Top) WindowInsets.safeDrawing.only(WindowInsetsSides.Top)
) )