Android Message Center
The default Message Center is available for iOS and Android. Minimal integration is required, and basic theming options are supported.
Installation
Message Center requires adding the urbanairship-message-center
module:
dependencies {
val airshipVersion = "18.6.0"
implementation("com.urbanairship.android:urbanairship-message-center:$airshipVersion")
}
dependencies {
def airshipVersion = "18.6.0"
implementation "com.urbanairship.android:urbanairship-message-center:$airshipVersion"
}
Listening for Inbox Updates
To listen for inbox changes, add a InboxListener the inbox to be notified whenever the message listing changes:
// Option 1: Messages Flow
scope.launch {
MessagesCenter.shared().inbox.getMessagesFlow().collect { messages ->
// ...
}
}
// Option 2: InboxListener
MessageCenter.shared().inbox.addListener(object: InboxListener {
override fun onInboxUpdated() {
// ...
}
})
MessageCenter.shared().getInbox().addListener(() -> {
// ...
});
Styling the Message Center
The Message Center can be styled via a combination of theme attributes and xml resource merging to override the default styles. The Message Center can be customized with the following theme attributes:
- messageCenterToolbarTitle
- String to use for the Message Center toolbar title
- messageCenterIconsEnabled
- Flag to enable message thumbnails in the message list
- messageCenterPlaceholderIcon
- The default placeholder image for message thumbnails
- messageCenterItemDividersEnabled
- Flag to enable dividers between messages in the list
- messageCenterItemDividerInsetStart
- The start inset for message list dividers
- messageCenterItemDividerInsetEnd
- The end inset for message list dividers
- dividerColor (set via Material Theme)
- The message list divider color, if dividers are enabled
Android resource merging can be used to further customize the default styles that the SDK provides. Copy portions or all of the style sheet
into the application’s styles.xml
or a new style resource, then change any of the styles.
<style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar">
<!-- ... -->
</style>
<!-- Custom Message Center style (using AppTheme colors as a base) -->
<style name="UrbanAirship.MessageCenter" parent="AppTheme">
<!-- Set custom toolbar title -->
<item name="messageCenterToolbarTitle">@string/inbox</item>
<!-- Show message thumbnails in the message list -->
<item name="messageCenterIconsEnabled">true</item>
<!-- MessageCenter specific colors can be set here (overriding any defaults from AppTheme) -->
</style>
<!-- Custom message title text appearance -->
<style name="UrbanAirship.MessageCenter.TextAppearance.MessageTitle" parent="TextAppearance.Material3.TitleMedium">
<item name="android:textStyle">italic</item>
</style>
<!-- Custom message date text appearance -->
<style name="UrbanAirship.MessageCenter.TextAppearance.MessageSentDate" parent="TextAppearance.Material3.BodySmall">
<item name="android:textStyle">italic</item>
<item name="android:textColor">?android:textColorSecondary</item>
</style>
Layout Support
The Message Center provides automatic support for both single-pane and two-pane layouts, when on large display sizes or foldable devices. In two-pane mode, the selected message is highlighted in the list and displayed in the detail pane. Right-to-left (RTL) layout is also supported when android:supportsRtl="true"
is set in your application manifest.
Message Center Filtering
Sometimes it can be useful to filter the contents of the Message Center according to some predetermined pattern. To facilitate this, use the shared MessageCenter instance to set a predicate. Once set, only messages that match the predicate will be displayed.
Filtering messages
MessageCenter.shared().predicate = Predicate { message ->
message.title.contains("Cool")
}
MessageCenter.shared().setPredicate(message ->
message.getTitle().contains("Cool")
);
Embedding the Message Center
Embedding MessageCenterFragment in an xml layout
The Message Center UI can be embedded in any FragmentActivity
or Fragment
using
MessageCenterFragment
.
When embedding the MessageCenterFragment, either use a FragmentContainerView
or create the fragment directly.
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_view"
android:name="com.urbanairship.messagecenter.ui.MessageCenterFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Instantiating a MessageCenterFragment
val fragment = MessageCenterFragment.newInstance()
MessageCenterFragment fragment = MessageCenterFragment.newInstance();
You will need to override the show behavior to navigate to your embedded fragment instead of letting Airship launch the MessageCenterActivity
.
Advanced embedding
For more control over the UI, MessageCenterListFragment
and MessageCenterMessageFragment
can be used to embed the list and message views separately, each maintaining its own Toolbar
.
This example assumes that Jetpack Navigation is being used to navigate between the list and message views, but any navigation method can be used.
class CustomMessageListFragment() : MessageCenterListFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
toolbar.inflateMenu(messageCenterR.menu.ua_message_center_list_pane_menu)
// Set up the toolbar, if desired.
setupWithNavController(toolbar, findNavController())
onMessageClickListener = OnMessageClickListener {
// Handle message clicks by navigating to the message fragment
// (or replace with custom navigation logic).
findNavController().navigate(
R.id.action_messageCenterFragment_to_messageFragment, bundleOf(
MessageCenterMessageFragment.ARG_MESSAGE_ID to it.id,
MessageCenterMessageFragment.ARG_MESSAGE_TITLE to it.title
)
)
}
}
}
class CustomMessageFragment : MessageCenterMessageFragment(R.layout.fragment_inbox_message) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
toolbar?.run {
// Inflate the default menu
inflateMenu(messageCenterR.menu.ua_message_center_message_pane_menu)
// Set up the toolbar, if desired.
setupWithNavController(toolbar, findNavController(view))
}
// Handle message deletion from the message view
onMessageDeletedListener = OnMessageDeletedListener {
// Handle message deletion by navigating back to the message list fragment
// (or replace with custom navigation logic).
findNavController().popBackStack()
// Optionally show a toast confirmation message
context?.run {
val msg = getQuantityString(messageCenterR.plurals.ua_mc_description_deleted, 1, 1)
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
}
}
}
}
These custom fragments can then be embedded into your app UI using FragmentContainerView
or by using FragmentManager
programmatically.
You will need to override the show behavior to navigate to your custom message list fragment instead of letting Airship launch the MessageCenterActivity
.
Categories