implement show/hide header on scroll in LibraryScreen and prevent haptic feedback on re-selecting the current bottom bar item

This commit is contained in:
jonasgaudian
2026-02-16 17:56:49 +01:00
parent eae37715cd
commit 47d7e01f7f
4 changed files with 87 additions and 43 deletions

View File

@@ -207,8 +207,10 @@ fun BottomNavigationBar(
NavigationBarItem(
selected = isSelected,
onClick = {
if (!isSelected) {
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
if (screen == Screen.More) showMoreMenu = true else onItemSelected(screen)
}
},
label = if (showLabels) {
{

View File

@@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
@@ -315,6 +316,7 @@ fun AllCardsView(
onItemClick: (VocabularyItem) -> Unit,
onItemLongClick: (VocabularyItem) -> Unit,
onDeleteClick: (VocabularyItem) -> Unit,
listState: LazyListState,
modifier: Modifier = Modifier
) {
if (vocabularyItems.isEmpty()) {
@@ -340,6 +342,7 @@ fun AllCardsView(
}
} else {
LazyColumn(
state = listState,
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier.fillMaxSize(),
contentPadding = PaddingValues(bottom = 100.dp)

View File

@@ -4,6 +4,10 @@ package eu.gaudian.translator.view.library
import android.os.Parcelable
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -42,6 +46,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
@@ -122,6 +127,10 @@ fun LibraryScreen(
val vocabularyItems by vocabularyItemsFlow.collectAsStateWithLifecycle(initialValue = emptyList())
var isHeaderVisible by remember { mutableStateOf(true) }
var previousIndex by remember { mutableStateOf(0) }
var previousScrollOffset by remember { mutableStateOf(0) }
// Set navigation context when vocabulary items are loaded
LaunchedEffect(vocabularyItems) {
if (vocabularyItems.isNotEmpty()) {
@@ -129,6 +138,24 @@ fun LibraryScreen(
}
}
LaunchedEffect(isCategoriesView, isInSelectionMode) {
if (isCategoriesView || isInSelectionMode) {
isHeaderVisible = true
}
}
LaunchedEffect(lazyListState, isCategoriesView, isInSelectionMode) {
if (isCategoriesView || isInSelectionMode) return@LaunchedEffect
snapshotFlow { lazyListState.firstVisibleItemIndex to lazyListState.firstVisibleItemScrollOffset }
.collect { (index, offset) ->
val isScrollingDown = index > previousIndex || (index == previousIndex && offset > previousScrollOffset)
val isAtTop = index == 0 && offset <= 4
isHeaderVisible = if (isAtTop) true else !isScrollingDown
previousIndex = index
previousScrollOffset = offset
}
}
Box(
modifier = modifier.fillMaxSize(),
contentAlignment = Alignment.TopCenter
@@ -139,6 +166,12 @@ fun LibraryScreen(
.fillMaxSize()
.padding(horizontal = 24.dp),
) {
AnimatedVisibility(
visible = isHeaderVisible,
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically()
) {
Column {
Spacer(modifier = Modifier.height(24.dp))
if (isInSelectionMode) {
@@ -180,6 +213,8 @@ fun LibraryScreen(
)
Spacer(modifier = Modifier.height(24.dp))
}
}
LibraryViewContainer(
isCategoriesView = isCategoriesView,
@@ -199,6 +234,7 @@ fun LibraryScreen(
vocabularyItems = vocabularyItems,
allLanguages = allLanguages,
selection = selection,
listState = lazyListState,
onItemClick = { item ->
if (isInSelectionMode) {
selection = if (selection.contains(item.id.toLong())) {

View File

@@ -268,6 +268,7 @@ fun NewVocListScreen(
vocabularyItems = vocabularyItems,
allLanguages = allLanguages,
selection = selection,
listState = lazyListState,
onItemClick = { item ->
if (isInSelectionMode) {
selection = if (selection.contains(item.id.toLong())) {
@@ -588,7 +589,8 @@ fun AllCardsView(
selection: Set<Long>,
onItemClick: (VocabularyItem) -> Unit,
onItemLongClick: (VocabularyItem) -> Unit,
onDeleteClick: (VocabularyItem) -> Unit
onDeleteClick: (VocabularyItem) -> Unit,
listState: androidx.compose.foundation.lazy.LazyListState
) {
if (vocabularyItems.isEmpty()) {
Column(
@@ -613,6 +615,7 @@ fun AllCardsView(
}
} else {
LazyColumn(
state = listState,
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(bottom = 100.dp)