Criar um layout personalizado de notificação

Para que suas notificações tenham a melhor aparência em diferentes versões do Android, use o modelo de notificação padrão para criar suas notificações. Se você quiser fornecer mais conteúdo na notificação, use um dos modelos de notificação expansíveis.

No entanto, caso os modelos do sistema não atendam às suas necessidades, você pode usar seu próprio layout para a notificação.

Criar layout personalizado para a área de conteúdo

Se você precisa de um layout personalizado, pode aplicar NotificationCompat.DecoratedCustomViewStyle à sua notificação. Essa API permite fornecer um layout personalizado para a área de conteúdo normalmente ocupada pelo título e pelo conteúdo do texto, enquanto ainda usa decorações do sistema para o ícone de notificação, o carimbo de data/hora, o subtexto e os botões de ação.

Essa API funciona de maneira semelhante aos modelos de notificação expansíveis criando o layout básico de notificação, da seguinte maneira:

  1. Crie uma notificação básica com NotificationCompat.Builder.
  2. Chame setStyle(), transmitindo uma instância de NotificationCompat.DecoratedCustomViewStyle.
  3. Infle o layout personalizado como uma instância de RemoteViews.
  4. Chame setCustomContentView() para definir o layout da notificação recolhida.
  5. Se quiser, chame também setCustomBigContentView() para definir um layout diferente para a notificação expandida.

Preparar os layouts

Você precisa dos layouts small e large. Para este exemplo, o layout small pode ficar assim:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/notification_title"
        style="@style/TextAppearance.Compat.Notification.Title"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="Small notification, showing only a title" />
</LinearLayout>

E o layout large vai ficar assim:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/notification_title"
        style="@style/TextAppearance.Compat.Notification.Title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Large notification, showing a title and a body." />

    <TextView
        android:id="@+id/notification_body"
        style="@style/TextAppearance.Compat.Notification.Line2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="This is the body. The height is manually forced to 300dp." />
</LinearLayout>

Criar e mostrar a notificação

Quando os layouts estiverem prontos, eles poderão ser usados conforme mostrado no exemplo a seguir:

Kotlin

val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

// Get the layouts to use in the custom notification.
val notificationLayout = RemoteViews(packageName, R.layout.notification_small)
val notificationLayoutExpanded = RemoteViews(packageName, R.layout.notification_large)

// Apply the layouts to the notification.
val customNotification = NotificationCompat.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setStyle(NotificationCompat.DecoratedCustomViewStyle())
        .setCustomContentView(notificationLayout)
        .setCustomBigContentView(notificationLayoutExpanded)
        .build()

notificationManager.notify(666, customNotification)

Java

NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

// Get the layouts to use in the custom notification
RemoteViews notificationLayout = new RemoteViews(getPackageName(), R.layout.notification_small);
RemoteViews notificationLayoutExpanded = new RemoteViews(getPackageName(), R.layout.notification_large);

// Apply the layouts to the notification.
Notification customNotification = new NotificationCompat.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setStyle(new NotificationCompat.DecoratedCustomViewStyle())
        .setCustomContentView(notificationLayout)
        .setCustomBigContentView(notificationLayoutExpanded)
        .build();

notificationManager.notify(666, customNotification);

Esteja ciente de que a cor de fundo da notificação pode variar de acordo com o dispositivo e a versão. Aplique estilos da Biblioteca de Suporte, como TextAppearance_Compat_Notification para o texto e TextAppearance_Compat_Notification_Title para o título no seu layout personalizado, conforme mostrado no exemplo abaixo. Esses estilos se adaptam às variações de cor para que você não acabe com texto preto sobre preto ou branco sobre branco.

<TextView
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:text="@string/notification_title"
    android:id="@+id/notification_title"
    style="@style/TextAppearance.Compat.Notification.Title" />

Evite definir uma imagem de plano de fundo no objeto RemoteViews, porque o texto pode ficar ilegível.

Quando você aciona uma notificação enquanto o usuário está usando um app, o resultado é semelhante à Figura 1:

Uma imagem mostrando uma notificação recolhida
Figura 1. Um pequeno layout de notificação aparece enquanto você usa outros apps.

Tocar na seta de expansão faz com que a notificação seja aberta, conforme mostrado na Figura 2:

Uma imagem mostrando uma notificação aberta na barra do sistema
Figura 2. Um layout de notificação grande aparece enquanto você usa outros apps.

Quando o tempo limite da notificação se esgotar, a notificação ficará visível apenas na barra do sistema, parecida com a Figura 3:

Imagem mostrando uma notificação recolhida na barra do sistema
Figura 3. Como o layout pequeno de notificação aparece na barra do sistema.

Tocar na seta de expansão faz com que a notificação seja aberta, conforme mostrado na Figura 4:

Uma imagem mostrando uma notificação aberta na barra do sistema
Figura 4. Um layout de notificação grande aparece na barra do sistema.

Criar um layout de notificação totalmente personalizado

Se você não quiser que sua notificação seja decorada com o ícone e o cabeçalho de notificação padrão, siga as etapas anteriores, mas não chame setStyle().