AepInbox
AepInbox is a Jetpack Compose composable that renders an Inbox UI based on the provided InboxUIState. It automatically handles different states (Loading, Success, Error) and renders the appropriate UI for each state.
Function Definition
Copied to your clipboard@Composablefun AepInbox(uiState: InboxUIState,inboxStyle: InboxUIStyle = InboxUIStyle.Builder().build(),itemsStyle: AepUIStyle = AepUIStyle(),observer: AepInboxEventObserver)
Parameters
| Parameter | Type | Description |
|---|---|---|
uiState | The current state of the Inbox UI. This determines what content is rendered: - InboxUIState.Loading - Displays the loading view- InboxUIState.Success - Displays the inbox with content cards- InboxUIState.Error - Displays the error view | |
inboxStyle | (optional) The style to customize the inbox container appearance, including heading, layout, empty state views, and unread indicators. Defaults to a standard inbox style. | |
itemsStyle | (optional) The style to customize individual content cards within the inbox. This allows styling of different card types (SmallImageUIStyle, LargeImageUIStyle, ImageOnlyUIStyle). Defaults to a standard card style. | |
observer | (required) An event observer that handles inbox-level events internally (such as inbox display tracking) and allows apps to listen to content card events (Display, Interact, Dismiss). Use InboxEventObserver which automatically handles inbox tracking and can optionally delegate card events to your ContentCardUIEventListener. |
Behavior
The AepInbox composable automatically:
- Handles State Changes: Responds to changes in
InboxUIStateand renders the appropriate UI - Supports Layouts: Renders inbox in vertical or horizontal layouts based on
InboxTemplate.layout - Manages Empty States: Displays custom empty message and image when no content cards are available
- Applies Unread Styling: Automatically applies unread background colors to unread content cards based on theme (light/dark) and configuration
- Wraps in Material Theme: Provides Material Theme context for proper rendering of text and other Material components
Example Usage
Do not embed AepInbox inside an unbounded container/lazy layout that scrolls in the same direction
AepInbox uses a LazyColumn for vertical layouts and a LazyRow for horizontal layouts. The orientation is set when the inbox campaign is authored and published on Adobe Journey Optimizer UI. Embedding AepInbox inside an unbounded container/lazy layout that scrolls in the same direction — such as a LazyColumn for a vertical scrolling inbox or a LazyRow for a horizontal scrolling inbox — causes a runtime crash (IllegalStateException: Vertically/Horizontally scrollable component was measured with an infinity maximum constraints).
Basic Usage
Copied to your clipboard@Composablefun InboxScreen(viewModel: InboxViewModel = viewModel()) {val inboxUIState by viewModel.inboxUIState.collectAsState()MaterialTheme {AepInbox(uiState = inboxUIState,observer = viewModel.observer)}}
With Custom Styling
Copied to your clipboard@Composablefun CustomInboxScreen(viewModel: InboxViewModel = viewModel()) {val inboxUIState by viewModel.inboxUIState.collectAsState()val inboxStyle = remember {InboxUIStyle.Builder().headingStyle(AepTextStyle(textStyle = TextStyle(fontWeight = FontWeight.Bold,fontSize = 24.sp))).unreadBgColor(AepColor(light = Color(0xFFE3F2FD),dark = Color(0xFF1E3A5F))).build()}val cardStyle = remember {AepUIStyle(smallImageUIStyle = SmallImageUIStyle.Builder().cardStyle(AepCardStyle(elevation = CardDefaults.cardElevation(defaultElevation = 4.dp))).build())}MaterialTheme {AepInbox(uiState = inboxUIState,inboxStyle = inboxStyle,itemsStyle = cardStyle,observer = viewModel.observer)}}
With Content Card Event Listener
To listen to content card events (display, interact, dismiss), implement ContentCardUIEventListener and pass it to the InboxEventObserver in your ViewModel:
Copied to your clipboardimport androidx.lifecycle.ViewModelimport androidx.lifecycle.viewModelScopeimport com.adobe.marketing.mobile.aepcomposeui.AepUIimport com.adobe.marketing.mobile.messaging.ContentCardEventObserverimport com.adobe.marketing.mobile.messaging.ContentCardUIEventListenerimport com.adobe.marketing.mobile.messaging.InboxEventObserverimport com.adobe.marketing.mobile.messaging.MessagingInboxProviderimport com.adobe.marketing.mobile.messaging.Surfaceimport kotlinx.coroutines.flow.SharingStartedimport kotlinx.coroutines.flow.stateIn// In ViewModel - observer survives configuration changesclass InboxViewModel : ViewModel() {private val cardEventListener = object : ContentCardUIEventListener {override fun onDisplay(aepUI: AepUI<*, *>) {// Called when a content card is displayed}override fun onInteract(aepUI: AepUI<*, *>,interactionId: String?,actionUrl: String?): Boolean {// Called when user taps on a card or button// Handle custom deep linksactionUrl?.let { url ->handleDeepLink(url)return true // Return true to indicate URL was handled}// Return false to let SDK handle the URL (open in browser)return false}override fun onDismiss(aepUI: AepUI<*, *>) {// Called when user dismisses a card}}val inboxProvider = MessagingInboxProvider(Surface("inbox"))val observer = InboxEventObserver(inboxProvider,ContentCardEventObserver(cardEventListener))val inboxUIState = inboxProvider.getInboxUI().stateIn(scope = viewModelScope,started = SharingStarted.WhileSubscribed(5000),initialValue = InboxUIState.Loading)}@Composablefun InboxWithEventsScreen(viewModel: InboxViewModel = viewModel()) {val inboxUIState by viewModel.inboxUIState.collectAsState()MaterialTheme {AepInbox(uiState = inboxUIState,observer = viewModel.observer)}}
For detailed information on the ContentCardUIEventListener callbacks, see ContentCardUIEventListener.
