Как создать собственный макет уведомления

Чтобы уведомления выглядели хорошо в разных версиях Android, используйте стандартный шаблон. Если вы хотите добавить в уведомление больше контента, используйте шаблоны разворачиваемых уведомлений.

Однако если системные шаблоны не соответствуют вашим потребностям, вы можете использовать собственный макет уведомления.

Создайте собственный макет для области контента.

Если вам нужен специальный макет, вы можете применить к уведомлению NotificationCompat.DecoratedCustomViewStyle. Этот API позволяет задать собственный макет для области контента, в которой обычно размещаются заголовок и текст, но при этом использовать системные элементы оформления для значка уведомления, временной метки, дополнительного текста и командных кнопок.

Этот API работает так же, как шаблоны разворачиваемых уведомлений, и позволяет создавать уведомления на основе базовой разметки следующим образом:

  1. Создайте простое уведомление с помощью NotificationCompat.Builder.
  2. Вызовите setStyle(), передав ему экземпляр NotificationCompat.DecoratedCustomViewStyle.
  3. Разверните макет как экземпляр RemoteViews.
  4. Вызовите метод setCustomContentView(), чтобы задать макет для свернутого уведомления.
  5. При необходимости вызовите метод setCustomBigContentView(), чтобы задать другой макет для развернутого уведомления.

Подготовка макетов

Вам понадобится макет small и large. В этом примере макет small может выглядеть следующим образом:

<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>

Макет large может выглядеть так:

<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>

Создание и показ уведомления

Когда макеты будут готовы, вы сможете использовать их, как показано в примере ниже.

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)

Учтите, что цвет фона уведомления может различаться в зависимости от устройства и версии. Примените стили библиотеки поддержки, например TextAppearance_Compat_Notification для текста и TextAppearance_Compat_Notification_Title для заголовка в специальном макете, как показано в примере ниже. Эти стили адаптируются к цветовым вариациям, поэтому текст не будет сливаться с фоном.

<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" />

Не устанавливайте фоновое изображение для объекта RemoteViews, так как текст может стать нечитаемым.

Если вы активируете уведомление, когда пользователь работает с приложением, результат будет похож на изображение 1:

Свернутый макет специального уведомления
Рисунок 1. Небольшое уведомление появляется, когда вы используете другие приложения.

Если нажать на стрелку, уведомление развернется, как показано на рисунке 2.

Развернутый макет специального уведомления
Рисунок 2. При использовании других приложений появляется большое уведомление.

По истечении времени ожидания уведомление будет видно только в системной строке, как показано на рисунке 3.

Свернутое уведомление в системной строке
Рисунок 3. Как выглядит макет небольшого уведомления в системной строке.

Если нажать на стрелку, уведомление развернется, как показано на рисунке 4.

Развернутое уведомление в системной строке
Рисунок 4. В системной строке появится большой макет уведомления.

Создание полностью настраиваемого макета уведомления

Если вы не хотите, чтобы в уведомлении показывались стандартные значок и заголовок, выполните описанные выше действия, но не вызывайте setStyle().