android: fix main tabs bar layout and content overlap
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user