Create a Notification Panel

Last edit: 2023.10.04

A notification itself is a panel, and a panel needs an IviFragment and a FrontendViewModel for the creation.

To create notifications, you need:

TomTom Digital Cockpit provides clients different ways for the notification creation. You can either use:

The following sections explain different ways to create a notification. An example app is provided in the examples/notifications directory.

Create a Stock Notification Panel

StockNotificationPanel is a notification panel which can only be created by StockNotificationPanel.Companion.create. You don't need to derive NotificationPanel, NotificationFragment, and NotificationViewModel yourself. You can just focus on providing data for the content.

The example below creates a notification when you click on the button. It demonstrates how you can create it by using StockNotificationPanel.Companion.create.

src/main/kotlin/com/example/ivi/example/notifications/NotificationCreationViewModel.kt

1import androidx.lifecycle.LiveData
2import com.tomtom.ivi.platform.frontend.api.common.frontend.panels.NotificationPanel
3import com.tomtom.ivi.platform.frontend.api.common.frontend.viewmodels.FrontendViewModel
4import com.tomtom.ivi.platform.frontend.api.template.notificationpanel.NotificationViewModel
5import com.tomtom.ivi.platform.frontend.api.template.notificationpanel.stock.StockNotificationPanel
6import com.tomtom.tools.android.api.livedata.ImmutableLiveData
7import com.tomtom.tools.android.api.resourceresolution.drawable.ResourceDrawableResolver
8import com.tomtom.tools.android.api.resourceresolution.string.StaticStringResolver
9import com.tomtom.tools.android.api.resourceresolution.string.StringResolver
10import com.tomtom.tools.android.api.uicontrols.button.TtButton
11import com.tomtom.tools.android.api.uicontrols.button.TtButtonViewModel
12import com.tomtom.tools.android.api.uicontrols.imageview.ImageDescriptor
13
14internal class NotificationCreationViewModel(panel: NotificationCreationPanel) :
15 FrontendViewModel<NotificationCreationPanel>(panel) {
16
17 fun onStockNotificationButtonClicked() =
18 panel.addPanel(
19 StockNotificationPanel.create {
20 frontendContext = panel.frontendContext
21 priority = NotificationPanel.Priority.HIGH
22 headerViewModel = HEADER
23 bodyText = BODY_TEXT
24 primaryActionButtonViewModel = PRIMARY_BUTTON
25 secondaryActionButtonViewModel = SECONDARY_BUTTON
26 optionViewModels = NOTIFICATION_OPTIONS
27 }
28 )
29
30 private companion object {
31 val HEADER = NotificationViewModel.HeaderViewModel(
32 imageDescriptor = ImageDescriptor(
33 ResourceDrawableResolver(R.drawable.ttivi_notification_icon_placeholder)
34 ),
35 title = StaticStringResolver("Stock"),
36 description = StaticStringResolver("Created by StockNotificationPanel.create")
37 )
38
39 val BODY_TEXT: LiveData<StringResolver?> =
40 ImmutableLiveData(StaticStringResolver("Body text"))
41
42 val PRIMARY_BUTTON: LiveData<TtButtonViewModel?> = ImmutableLiveData(
43 TtButtonViewModel(
44 text = StaticStringResolver("Primary"),
45 actionType = TtButton.ActionType.PRIMARY
46 )
47 )
48
49 val SECONDARY_BUTTON: LiveData<TtButtonViewModel?> = ImmutableLiveData(
50 TtButtonViewModel(
51 text = StaticStringResolver("Secondary"),
52 actionType = TtButton.ActionType.DESTRUCTIVE
53 )
54 )
55
56 val NOTIFICATION_OPTIONS = ImmutableLiveData(
57 listOf(
58 NotificationViewModel.OptionViewModel(
59 description = ImmutableLiveData(
60 StaticStringResolver("Notification option")
61 )
62 )
63 )
64 )
65 }
66}
Stock notification panel

Implement your own Notification Panel

If you need more complex logic for notifications, for example extra actions to be performed when a notification is dismissed, you can implement NotificationPanel yourself. The example below is similar to the previous one, except we choose to implement NotificationPanel manually.

src/main/kotlin/com/example/ivi/example/notifications/ExampleNotificationPanel.kt

1import androidx.lifecycle.LiveData
2import com.tomtom.ivi.platform.frontend.api.common.frontend.FrontendContext
3import com.tomtom.ivi.platform.frontend.api.common.frontend.IviFragment
4import com.tomtom.ivi.platform.frontend.api.common.frontend.panels.DismissalState
5import com.tomtom.ivi.platform.frontend.api.common.frontend.panels.NotificationPanel
6import com.tomtom.ivi.platform.frontend.api.template.notificationpanel.NotificationFragment
7import com.tomtom.ivi.platform.frontend.api.common.frontend.viewmodels.FrontendViewModel
8import com.tomtom.ivi.platform.frontend.api.template.notificationpanel.NotificationViewModel
9import com.tomtom.tools.android.api.livedata.ImmutableLiveData
10import com.tomtom.tools.android.api.livedata.valueUpToDate
11import com.tomtom.tools.android.api.resourceresolution.drawable.ResourceDrawableResolver
12import com.tomtom.tools.android.api.resourceresolution.string.StaticStringResolver
13import com.tomtom.tools.android.api.resourceresolution.string.StringResolver
14import com.tomtom.tools.android.api.uicontrols.button.TtButton
15import com.tomtom.tools.android.api.uicontrols.button.TtButtonViewModel
16import com.tomtom.tools.android.api.uicontrols.imageview.ImageDescriptor
17
18internal class NotificationCreationViewModel(panel: NotificationCreationPanel) :
19 FrontendViewModel<NotificationCreationPanel>(panel) {
20
21 fun onCustomNotificationButtonClicked() =
22 panel.addPanel(ExampleNotificationPanel(panel.frontendContext))
23}
24
25internal class ExampleNotificationPanel(
26 frontendContext: FrontendContext
27) : NotificationPanel(frontendContext, Priority.HIGH) {
28
29 override fun createInitialFragmentInitializer() =
30 IviFragment.Initializer(
31 NotificationFragment(ExampleNotificationViewModel::class),
32 this
33 )
34
35 override fun onRemovedFromFrontend() {
36 if (dismissalState.valueUpToDate == DismissalState.DISMISSED) {
37 onDismissedAction()
38 }
39 super.onRemovedFromFrontend()
40 }
41
42 private fun onDismissedAction() {
43 // Things to do when the panel is dismissed by the user.
44 }
45}

src/main/kotlin/com/example/ivi/example/notifications/ExampleNotificationViewModel.kt

1
2internal class ExampleNotificationViewModel(panel: ExampleNotificationPanel) :
3 NotificationViewModel<ExampleNotificationPanel>(panel){
4
5 override val headerViewModel = HeaderViewModel(
6 imageDescriptor = ImageDescriptor(
7 ResourceDrawableResolver(R.drawable.ttivi_notification_icon_alternative_placeholder)
8 ),
9 title = StaticStringResolver("Custom"),
10 description = StaticStringResolver("Extend from NotificationPanel")
11 )
12
13 override val bodyText: LiveData<StringResolver?> =
14 ImmutableLiveData(StaticStringResolver("Body text"))
15
16 override val primaryActionButtonViewModel: LiveData<TtButtonViewModel?> =
17 ImmutableLiveData(
18 TtButtonViewModel(
19 text = StaticStringResolver("Primary"),
20 actionType = TtButton.ActionType.ACCEPTANCE,
21 onClick = { onPrimaryButtonClicked() }
22 )
23 )
24
25 private fun onPrimaryButtonClicked() {
26 // Things to be executed when the primary button is clicked.
27 }
28
29 override val secondaryActionButtonViewModel: LiveData<TtButtonViewModel?> = ImmutableLiveData(
30 TtButtonViewModel(
31 text = StaticStringResolver("Secondary"),
32 actionType = TtButton.ActionType.DESTRUCTIVE,
33 onClick = { onSecondaryButtonClicked() }
34 )
35 )
36
37 private fun onSecondaryButtonClicked() {
38 // Things to be executed when the secondary button is clicked.
39 }
40
41 override val optionViewModels: LiveData<List<OptionViewModel>> = ImmutableLiveData(
42 listOf(
43 OptionViewModel(
44 imageDescriptor = ImmutableLiveData(
45 ImageDescriptor(
46 ResourceDrawableResolver(R.drawable.ttivi_notificationoption_icon_placeholder)
47 ),
48 ),
49 description = ImmutableLiveData(
50 StaticStringResolver("Notification option")
51 ),
52 )
53 )
54 )
55}
Custom notification panel