Sometimes notifications created by the builder just don't provide enough flexibility compared to what is required. Sometimes notifications created by the builder just don't provide enough flexibility or customization. As a result, an entirely custom notification layout is needed to provide this level of customization.
If we are going to support Android versions prior to 3.0, we will have to install the Xamarin Support Library v4 NuGet or component into our project.
We can use RemoteViews
with a layout file to provide a custom layout for a notification:
RemoteViews
object, passing the resource ID of the layout:var view = new RemoteViews( PackageName, Resource.Layout.NotificationLayout);
SetTextViewText()
, SetProgressBar()
, and SetImageViewResource()
:view.SetTextViewText(Resource.Id.title, "Title Text"); view.SetProgressBar(Resource.Id.progress, 100, 25, false); view.SetImageViewResource( Resource.Id.state, Resource.Drawable.state);
Intent
instance for the notification:var intent = new Intent(this, typeof(MainActivity)); var pendingIntent = PendingIntent.GetActivity( this, 0, intent, PendingIntentFlags.UpdateCurrent);
var notification = new NotificationCompat.Builder(this) .SetSmallIcon(Android.Resource.Drawable.StatNotifySync) .SetAutoCancel(true) .SetContentIntent(pendingIntent) .SetContent(view);
manager.Notify(CustomId, notification.Build());
RemoteViews
object and notifying the NotificationManager
instance:view.SetTextViewText(Resource.Id.title, "Updated!"); manager.Notify(SimpleId, notification.Build());
Some notifications require a custom layout, especially if they have to present advanced data. The notification builder provides many features, but sometimes this is not flexible enough to present the required data to the user.
To display a custom layout, we first define the layout in a resource file just like any other layout. However, not all view elements can be used easily as the views are not exposed publicly. The views are accessed by various setter methods instead of directly. Views such as TextView
and ImageView
can be used, but custom views with complex properties or methods cannot be modified.
To build the notification view, we construct an instance of RemoteViews
, providing a package name and the layout resource ID in that package. Usually, we will use the current package name and a resource in our app.
We can update the notification view and set any properties using the methods on the RemoteViews
object. The values set are stored and then applied when the notification is presented. There are various methods that are available, such as SetTextViewText()
or SetProgressBar()
, that make updating certain types of views easy. Properties are set by providing the view ID and the value. There are also the type setter methods, such as SetString()
and SetInt()
, that can be used to set arbitrary properties of a view.
To create the notification, we still create an instance of the notification builder, but the difference now is to set the content. Instead of setting the title or content text, we rather just set the SetContent()
method with the RemoteViews
object.
At the time of writing, there is a bug in the Android support library, which prevents the custom view from loading on Android versions prior to 3.0. A workaround is to set the content view on the built notification:
var notification = notificationBuilder.Build(); if (Build.VERSION.SdkInt < BuildVersionCodes.Honeycomb) { notification.ContentView = remoteViews; }
To update the notification, we just need to update the RemoteViews
object and invoke the Notify()
method again.
We can also create notifications using RemoteViews
directly without having to use the notification builder or the Android support library. This is similar to using the builder, but instead of creating an instance of the builder, we construct an instance of Notification
. We then set the various properties on the notification, such as Title
, Icon
, ContentIntent
, and ContentView
.
Although possible, this is often unnecessary and introduces complications. One such complication is that the notification will not be synchronized with any paired wearables.