android: fix main tabs bar layout and content overlap
Some checks failed
Android CI / android (push) Failing after 5m15s
Android Release / release (push) Failing after 5m18s
CI / test (push) Failing after 2m26s

This commit is contained in:
Codex
2026-03-09 20:29:05 +03:00
parent d29ad4cfb7
commit 3af90ec257
6 changed files with 41 additions and 59 deletions

View File

@@ -482,3 +482,8 @@
- Implemented scroll-direction behavior for all 4 main pages:
- hide panel on downward scroll,
- show panel on upward scroll / at top.
### Step 77 - Main tabs bar UX/layout fix
- Replaced custom pill-row main bar with compact `NavigationBar` inside rounded container for stable 4-tab layout on small screens.
- Added bottom content paddings for `Chats/Contacts/Settings/Profile` pages so content is not obscured by the floating main bar.
- Raised chats management FAB offset to avoid overlap with the global bottom bar.

View File

@@ -169,7 +169,8 @@ fun ChatListScreen(
Column(
modifier = Modifier
.fillMaxSize()
.then(if (isTabletLayout) Modifier.widthIn(max = 820.dp) else Modifier),
.then(if (isTabletLayout) Modifier.widthIn(max = 820.dp) else Modifier)
.padding(bottom = 92.dp),
) {
TabRow(
selectedTabIndex = if (state.selectedTab == ChatTab.ALL) 0 else 1,
@@ -318,7 +319,7 @@ fun ChatListScreen(
onClick = { managementExpanded = !managementExpanded },
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(end = 16.dp, bottom = 88.dp),
.padding(end = 16.dp, bottom = 112.dp),
) {
Icon(
imageVector = if (managementExpanded) Icons.Filled.Close else Icons.Filled.Add,

View File

@@ -84,7 +84,7 @@ private fun ContactsScreen(
modifier = Modifier
.fillMaxWidth()
.then(if (isTabletLayout) Modifier.widthIn(max = 820.dp) else Modifier)
.padding(16.dp),
.padding(start = 16.dp, top = 16.dp, end = 16.dp, bottom = 96.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
Text(

View File

@@ -8,9 +8,9 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.padding
@@ -24,8 +24,9 @@ import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Icon
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
@@ -42,8 +43,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.core.content.ContextCompat
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavType
@@ -295,71 +295,47 @@ private fun MainBottomBar(
onNavigate: (String) -> Unit,
) {
Surface(
modifier = Modifier
.padding(horizontal = 12.dp)
.fillMaxWidth(),
shape = CircleShape,
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.92f),
) {
androidx.compose.foundation.layout.Row(
modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
NavigationBar(
containerColor = androidx.compose.ui.graphics.Color.Transparent,
tonalElevation = 0.dp,
modifier = Modifier.padding(horizontal = 8.dp),
) {
MainTabPill(
label = "Chats",
NavigationBarItem(
selected = currentRoute == Routes.Chats,
icon = { Icon(Icons.AutoMirrored.Filled.Chat, contentDescription = null) },
onClick = { onNavigate(Routes.Chats) },
icon = { Icon(Icons.AutoMirrored.Filled.Chat, contentDescription = "Chats") },
label = {
androidx.compose.material3.Text("Chats", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
)
MainTabPill(
label = "Contacts",
NavigationBarItem(
selected = currentRoute == Routes.Contacts,
icon = { Icon(Icons.Filled.Contacts, contentDescription = null) },
onClick = { onNavigate(Routes.Contacts) },
icon = { Icon(Icons.Filled.Contacts, contentDescription = "Contacts") },
label = {
androidx.compose.material3.Text("Contacts", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
)
MainTabPill(
label = "Settings",
NavigationBarItem(
selected = currentRoute == Routes.Settings,
icon = { Icon(Icons.Filled.Settings, contentDescription = null) },
onClick = { onNavigate(Routes.Settings) },
icon = { Icon(Icons.Filled.Settings, contentDescription = "Settings") },
label = {
androidx.compose.material3.Text("Settings", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
)
MainTabPill(
label = "Profile",
NavigationBarItem(
selected = currentRoute == Routes.Profile,
icon = { Icon(Icons.Filled.Person, contentDescription = null) },
onClick = { onNavigate(Routes.Profile) },
)
}
}
}
@Composable
private fun MainTabPill(
label: String,
selected: Boolean,
icon: @Composable () -> Unit,
onClick: () -> Unit,
) {
Surface(
shape = CircleShape,
color = if (selected) {
MaterialTheme.colorScheme.primaryContainer
} else {
MaterialTheme.colorScheme.surface
},
modifier = Modifier
.clickable(onClick = onClick)
.semantics { contentDescription = "$label tab" },
) {
androidx.compose.foundation.layout.Row(
modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp),
horizontalArrangement = Arrangement.spacedBy(6.dp),
verticalAlignment = Alignment.CenterVertically,
) {
icon()
Text(
text = label,
color = if (selected) {
MaterialTheme.colorScheme.onPrimaryContainer
} else {
MaterialTheme.colorScheme.onSurface
icon = { Icon(Icons.Filled.Person, contentDescription = "Profile") },
label = {
androidx.compose.material3.Text("Profile", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
)
}

View File

@@ -125,7 +125,7 @@ fun ProfileScreen(
.fillMaxWidth()
.then(if (isTabletLayout) Modifier.widthIn(max = 720.dp) else Modifier)
.verticalScroll(scrollState)
.padding(16.dp),
.padding(start = 16.dp, top = 16.dp, end = 16.dp, bottom = 96.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
Text(

View File

@@ -105,7 +105,7 @@ fun SettingsScreen(
.fillMaxWidth()
.then(if (isTabletLayout) Modifier.widthIn(max = 720.dp) else Modifier)
.verticalScroll(scrollState)
.padding(16.dp),
.padding(start = 16.dp, top = 16.dp, end = 16.dp, bottom = 96.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
Text(