Skip to content

Commit b51bd5e

Browse files
committed
feat: Improve bottom navigation bar accessibility and add auto-hide feature
- Improve the accessibility of the bottom navigation bar by adding semantics for tab roles, selection status, and content descriptions. - Add an auto-hide feature to the bottom navigation bar, triggered by accessibility touch events. - Refactor bottom navigation bar `alwaysShowLabel` property.
1 parent 1e975a8 commit b51bd5e

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

app/src/main/java/com/github/jing332/tts_server_android/compose/MainPager.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,14 @@ import androidx.compose.runtime.rememberCoroutineScope
3131
import androidx.compose.ui.Modifier
3232
import androidx.compose.ui.graphics.Color
3333
import androidx.compose.ui.input.nestedscroll.nestedScroll
34+
import androidx.compose.ui.platform.LocalContext
3435
import androidx.compose.ui.res.stringResource
36+
import androidx.compose.ui.semantics.Role
37+
import androidx.compose.ui.semantics.clearAndSetSemantics
38+
import androidx.compose.ui.semantics.contentDescription
39+
import androidx.compose.ui.semantics.role
40+
import androidx.compose.ui.semantics.selected
41+
import com.github.jing332.compose.widgets.ControlBottomBarVisibility
3542
import com.github.jing332.compose.widgets.rememberA11TouchEnabled
3643
import com.github.jing332.tts_server_android.compose.forwarder.systts.SystemTtsForwarderScreen
3744
import com.github.jing332.tts_server_android.compose.settings.SettingsScreen
@@ -62,13 +69,15 @@ fun AnimatedContentScope.MainPager(sharedVM: SharedViewModel) {
6269
}
6370
}
6471

72+
val context = LocalContext.current
6573
val scope = rememberCoroutineScope()
6674
MigrationTips()
6775

6876
val a11yTouchEnabled = rememberA11TouchEnabled()
6977
val scrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior(canScroll = {
7078
!a11yTouchEnabled
7179
})
80+
ControlBottomBarVisibility(a11yTouchEnabled, scrollBehavior)
7281

7382
val overlayController = rememberOverlayController()
7483

@@ -115,8 +124,13 @@ fun AnimatedContentScope.MainPager(sharedVM: SharedViewModel) {
115124
for (destination in PagerDestination.routes) {
116125
val isSelected = pagerState.currentPage == destination.index
117126
NavigationBarItem(
127+
modifier = Modifier.clearAndSetSemantics {
128+
role = Role.Tab
129+
selected = isSelected
130+
contentDescription = context.getString(destination.strId)
131+
},
118132
selected = isSelected,
119-
alwaysShowLabel = a11yTouchEnabled,
133+
alwaysShowLabel = false,
120134
onClick = {
121135
scope.launch {
122136
pagerState.animateScrollToPage(destination.index)

lib-compose/src/main/java/com/github/jing332/compose/widgets/ControlBottomBarVisibility.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,36 @@ import androidx.compose.runtime.LaunchedEffect
1010
import androidx.compose.runtime.remember
1111

1212

13+
@OptIn(ExperimentalMaterial3Api::class)
14+
@Composable
15+
fun ControlBottomBarVisibility(
16+
state: Boolean,
17+
bottomBarBehavior: BottomAppBarScrollBehavior,
18+
) {
19+
val bottomAppBarState = bottomBarBehavior.state
20+
21+
val heightOffset =
22+
remember { androidx.compose.animation.core.Animatable(1f) }
23+
24+
LaunchedEffect(heightOffset.value) {
25+
bottomAppBarState.heightOffset = heightOffset.value
26+
}
27+
28+
LaunchedEffect(state) {
29+
if (state) {
30+
heightOffset.snapTo(bottomAppBarState.heightOffset)
31+
heightOffset.animateTo(
32+
targetValue = 0f,
33+
animationSpec = tween(
34+
durationMillis = 300,
35+
easing = FastOutSlowInEasing
36+
)
37+
)
38+
}
39+
}
40+
41+
}
42+
1343
@OptIn(ExperimentalMaterial3Api::class)
1444
@Composable
1545
fun ControlBottomBarVisibility(

0 commit comments

Comments
 (0)