Customizing Inbox
This tutorial explains how to customize the appearance and behavior of the Inbox in your Android application.
Overview
The AepInbox composable provides extensive customization options to match your app's design system. You can customize:
- Inbox Container: Heading, list layout, padding, and spacing
- Custom Views: Loading, error, and empty state views
- Unread Indicators: Icon style, alignment, and background color
- Content Cards: Individual card appearance through
AepUIStyle
All customizations are applied using the InboxUIStyle builder and AepUIStyle when rendering the AepInbox composable.
Customizing Inbox Container Style
The InboxUIStyle class provides a builder pattern to customize the inbox container appearance and custom views.
Heading Style
Customize the heading text appearance using AepTextStyle:
Copied to your clipboardimport com.adobe.marketing.mobile.aepcomposeui.style.AepTextStyleimport com.adobe.marketing.mobile.aepcomposeui.style.InboxUIStyleimport androidx.compose.ui.text.TextStyleimport androidx.compose.ui.text.font.FontWeightimport androidx.compose.ui.text.style.TextAlignimport androidx.compose.ui.unit.spval headingStyle = AepTextStyle(modifier = Modifier.fillMaxWidth().padding(16.dp),textStyle = TextStyle(color = MaterialTheme.colorScheme.onSurface,fontWeight = FontWeight.Bold,fontSize = 24.sp,textAlign = TextAlign.Start))val inboxStyle = InboxUIStyle.Builder().headingStyle(headingStyle).build()
Vertical Layout (LazyColumn) Style
For vertical inbox layouts, customize the LazyColumn using AepLazyColumnStyle:
Copied to your clipboardimport com.adobe.marketing.mobile.aepcomposeui.style.AepLazyColumnStyleimport androidx.compose.foundation.layout.Arrangementimport androidx.compose.foundation.layout.PaddingValuesimport androidx.compose.ui.Alignmentval lazyColumnStyle = AepLazyColumnStyle(modifier = Modifier.fillMaxSize().background(Color.LightGray),contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp),verticalArrangement = Arrangement.spacedBy(12.dp),horizontalAlignment = Alignment.CenterHorizontally)val inboxStyle = InboxUIStyle.Builder().lazyColumnStyle(lazyColumnStyle).build()
Horizontal Layout (LazyRow) Style
For horizontal inbox layouts, customize the LazyRow using AepLazyRowStyle:
Copied to your clipboardimport com.adobe.marketing.mobile.aepcomposeui.style.AepLazyRowStyleval lazyRowStyle = AepLazyRowStyle(modifier = Modifier.height(250.dp).background(Color.DarkGray),contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp),horizontalArrangement = Arrangement.spacedBy(12.dp),verticalAlignment = Alignment.CenterVertically)val inboxStyle = InboxUIStyle.Builder().lazyRowStyle(lazyRowStyle).build()
Custom Views
The Inbox provides hooks to replace the default loading, error, and empty state views with your own custom composables.
Custom Loading View
Replace the default loading indicator with your own custom view:
Copied to your clipboardval inboxStyle = InboxUIStyle.Builder().loadingView {Box(modifier = Modifier.fillMaxSize(),contentAlignment = Alignment.Center) {Column(horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.spacedBy(16.dp)) {CircularProgressIndicator(modifier = Modifier.size(48.dp),color = MaterialTheme.colorScheme.primary)Text(text = "Loading your inbox...",style = MaterialTheme.typography.bodyLarge,color = MaterialTheme.colorScheme.onSurfaceVariant)}}}.build()
Custom Error View
Replace the default error view with your own custom view:
Copied to your clipboardval inboxStyle = InboxUIStyle.Builder().errorView {Column(modifier = Modifier.fillMaxSize().padding(32.dp),horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.Center) {Icon(imageVector = Icons.Default.Warning,contentDescription = "Error",modifier = Modifier.size(64.dp),tint = MaterialTheme.colorScheme.error)Spacer(modifier = Modifier.height(16.dp))Text(text = "Unable to load inbox",style = MaterialTheme.typography.titleLarge,color = MaterialTheme.colorScheme.onSurface)Spacer(modifier = Modifier.height(8.dp))Text(text = "Please check your connection and try again",style = MaterialTheme.typography.bodyMedium,color = MaterialTheme.colorScheme.onSurfaceVariant,textAlign = TextAlign.Center)Spacer(modifier = Modifier.height(24.dp))Button(onClick = { viewModel.refresh() }) {Text("Retry")}}}.build()
Empty State Style
Customize the appearance of the empty state message and image:
Copied to your clipboardval emptyMessageStyle = AepTextStyle(modifier = Modifier.padding(16.dp),textStyle = TextStyle(fontSize = 18.sp,color = Color.Gray,textAlign = TextAlign.Center))val emptyImageStyle = AepImageStyle(modifier = Modifier.size(120.dp))val inboxStyle = InboxUIStyle.Builder().emptyMessageStyle(emptyMessageStyle).emptyImageStyle(emptyImageStyle).build()
Unread Indicator Customization
Customize how unread messages are visually distinguished in the inbox.
Unread Icon Style
Customize the unread indicator icon:
Copied to your clipboardimport com.adobe.marketing.mobile.aepcomposeui.style.AepImageStyleval unreadIconStyle = AepImageStyle(modifier = Modifier.padding(8.dp).size(24.dp))val inboxStyle = InboxUIStyle.Builder().unreadIconStyle(unreadIconStyle).build()
Unread Icon Alignment
Set the position of the unread indicator icon on the card:
Copied to your clipboardimport androidx.compose.ui.Alignmentval inboxStyle = InboxUIStyle.Builder().unreadIconAlignment(Alignment.TopEnd) // TopStart, TopEnd, BottomStart, BottomEnd.build()
Unread Background Color
Set a custom background color for unread cards that adapts to light and dark themes:
Copied to your clipboardimport com.adobe.marketing.mobile.aepcomposeui.uimodels.AepColorimport androidx.compose.ui.graphics.Colorval unreadBgColor = AepColor(light = Color(0xFFE3F2FD), // Light blue for light themedark = Color(0xFF1E3A5F) // Dark blue for dark theme)val inboxStyle = InboxUIStyle.Builder().unreadBgColor(unreadBgColor).build()
For detailed information on all available style classes and their properties, see InboxUIStyle.
Customizing Content Cards
Individual content cards within the Inbox can be customized using AepUIStyle. This allows you to style different card types (SmallImage, LargeImage, ImageOnly) independently.
Applying Content Card Styles
Copied to your clipboardimport com.adobe.marketing.mobile.aepcomposeui.style.AepCardStyleimport com.adobe.marketing.mobile.aepcomposeui.style.AepUIStyleimport com.adobe.marketing.mobile.aepcomposeui.style.SmallImageUIStyleimport com.adobe.marketing.mobile.aepcomposeui.style.LargeImageUIStyleimport com.adobe.marketing.mobile.aepcomposeui.style.ImageOnlyUIStyle// Define card styleval cardStyle = AepCardStyle(modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp))// Create styles for each card typeval smallImageCardStyle = SmallImageUIStyle.Builder().cardStyle(cardStyle).titleAepTextStyle(AepTextStyle(textStyle = TextStyle(fontWeight = FontWeight.SemiBold,fontSize = 16.sp))).bodyAepTextStyle(AepTextStyle(textStyle = TextStyle(fontSize = 14.sp,color = Color.Gray))).build()val largeImageCardStyle = LargeImageUIStyle.Builder().cardStyle(cardStyle).build()val imageOnlyCardStyle = ImageOnlyUIStyle.Builder().cardStyle(cardStyle).build()// Combine into AepUIStyleval cardUIStyle = AepUIStyle(smallImageUIStyle = smallImageCardStyle,largeImageUIStyle = largeImageCardStyle,imageOnlyUIStyle = imageOnlyCardStyle)// Apply to AepInboxAepInbox(uiState = inboxUIState,inboxStyle = inboxStyle,itemsStyle = cardUIStyle,observer = viewModel.observer)
For detailed information on customizing content cards, see Customizing Content Card Templates.
Best Practices
1. Test Light and Dark Modes
Always test your customizations in both light and dark mode. Use AepColor for theme-aware colors:
Copied to your clipboardval unreadBgColor = AepColor(light = Color(0xFFE3F2FD), // Light theme colordark = Color(0xFF1E3A5F) // Dark theme color)
2. Use Material Theme Colors
Leverage Material Theme for consistent styling that adapts to your app's theme:
Copied to your clipboardval headingStyle = AepTextStyle(textStyle = TextStyle(color = MaterialTheme.colorScheme.onSurface,fontSize = MaterialTheme.typography.titleLarge.fontSize))
3. Keep Custom Views Lightweight
Avoid complex or heavy composables in custom loading, error, and empty views to maintain smooth performance.
4. Maintain Consistency
Keep your inbox customizations consistent with your app's overall design system by defining reusable style constants:
Copied to your clipboardobject InboxDesignSystem {val cardPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp)val cardSpacing = 12.dpval headingFontSize = 22.sp}
5. Remember Style Objects
Use remember for style objects that don't change to avoid unnecessary recomposition:
Copied to your clipboard@Composablefun InboxScreen(viewModel: InboxViewModel) {val inboxUIState by viewModel.inboxUIState.collectAsStateWithLifecycle()val inboxStyle = remember {InboxUIStyle.Builder().headingStyle(headingStyle).lazyColumnStyle(lazyColumnStyle).build()}AepInbox(uiState = inboxUIState,inboxStyle = inboxStyle,observer = viewModel.observer)}
6. Ensure Accessibility
Follow Android accessibility guidelines when customizing:
- Maintain sufficient color contrast ratios (4.5:1 for normal text, 3:1 for large text)
- Ensure touch targets are at least 48dp × 48dp
- Use semantic colors that convey meaning in both light and dark themes
7. Consider Screen Sizes
Design your inbox customizations to work across different screen sizes. Use responsive modifiers and avoid fixed widths:
Copied to your clipboardval cardStyle = AepCardStyle(modifier = Modifier.fillMaxWidth() // Adapts to screen width.padding(horizontal = 16.dp, vertical = 8.dp))
