Custom Layout for Push Notification with multiple click & Collapsed-Expanded Notification

Walaupun sebenarnya dari pihak Google sudah menyediakan beberapa design untuk digunakan seperti yang telah dituliskan pada laman mereka.

Namun terdapat beberapa kekurangan saat ingin mengimplementasikanya agar dapat kompatibel dengan beberapa API berbeda. Dan beberapa bagian yang disupport untuk semua API hanya terdapat beberapa saja, diantaranya :

  1. Ikon kecil: Ini diperlukan dan disetel dengan setSmallIcon().
  2. Nama aplikasi: Ini disediakan oleh sistem.
  3. Stempel waktu: Ini disediakan oleh sistem tetapi Anda dapat menggantinya dengan setWhen() atau menyembunyikannya dengan setShowWhen(false).
  4. Ikon besar: Ini opsional (biasanya hanya digunakan untuk foto kontak; jangan gunakan untuk ikon aplikasi Anda) dan setel dengan setLargeIcon().
  5. Judul: Ini opsional dan disetel dengan setContentTitle().
  6. Teks: Ini opsional dan disetel dengan setContentText().

Lagipula seringkali developer diharuskan membuat custom display tergantung dengan kebutuhan aplikasinya. Jadi kali ini saya akan menjelaskan secara singkat saja bagaimana cara membuat tampilan push notification secara custom dengan menggunakan layout yang dapat kita desain melalui xml layaknya layout untuk standard custom view .

  1. Buat custom layout :

  • view_collapsed_notification.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="8dp">

    <RelativeLayout
        android:id="@+id/icon_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/big_icon"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:paddingBottom="1dp"
            android:paddingStart="4dp"
            android:paddingEnd="6dp"
            android:src="@drawable/task_to_do"/>

        <ImageView
            android:id="@+id/small_icon"
            android:layout_width="18.2dp"
            android:layout_height="18.2dp"
            android:layout_alignBottom="@id/big_icon"
            android:layout_alignEnd="@id/big_icon"
            android:src="@drawable/ic_triple_arrow_down_yellow"/>

    </RelativeLayout>

    <LinearLayout
        android:id="@+id/notification_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="false"
        android:layout_marginTop="3dp"
        android:layout_toEndOf="@+id/icon_container"
        android:gravity="center_vertical"
        android:orientation="vertical"
        android:paddingStart="6dp">

        <TextView
            android:id="@+id/content_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Found a New Trip"
            android:textAppearance="@style/TextAppearance.Compat.Notification.Title"/>

        <TextView
            android:id="@+id/content_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Expand to see the details"
            android:textAppearance="@style/TextAppearance.Compat.Notification"/>
    </LinearLayout>

    <TextView
        android:id="@+id/timestamp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentTop="true"
        android:paddingEnd="3.5dp"
        android:paddingTop="8dp"
        android:textAppearance="@style/TextAppearance.Compat.Notification.Time"/>

</RelativeLayout>
  • view_expanded_notification.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="8dp">

    <RelativeLayout
        android:id="@+id/icon_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/big_icon"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:paddingBottom="1dp"
            android:paddingStart="4dp"
            android:paddingEnd="6dp"
            android:src="@drawable/task_to_do"/>

        <ImageView
            android:id="@+id/small_icon"
            android:layout_width="18.2dp"
            android:layout_height="18.2dp"
            android:scaleY="-1"
            android:layout_alignBottom="@id/big_icon"
            android:layout_alignEnd="@id/big_icon"
            android:src="@drawable/ic_triple_arrow_down_yellow"/>

    </RelativeLayout>

    <LinearLayout
        android:id="@+id/notification_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="false"
        android:layout_marginTop="3dp"
        android:layout_toEndOf="@+id/icon_container"
        android:gravity="center_vertical"
        android:orientation="vertical"
        android:paddingStart="6dp">

        <TextView
            android:id="@+id/content_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Found a New Trip"
            android:textAppearance="@style/TextAppearance.Compat.Notification.Title"/>

        <TextView
            android:id="@+id/content_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Here is the detail :"
            android:textAppearance="@style/TextAppearance.Compat.Notification"/>
    </LinearLayout>



    <LinearLayout
        android:id="@+id/notification_info"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/space_s"
        android:layout_below="@id/icon_container"
        android:layout_marginTop="8dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tx_title_notification"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="@dimen/font_xxl"
            android:layout_marginBottom="@dimen/space_m"
            android:ellipsize="end"
            android:maxLines="1"
            android:textAllCaps="true"
            android:textStyle="bold"
            android:gravity="center"
            android:textAppearance="@style/TextAppearance.Compat.Notification.Info"
            tools:text="PRE START UP - KMJ UNIT 4 TRIP" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:weightSum="2"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tx_cause_desc"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/space_xl"
                android:layout_weight="1"
                android:ellipsize="end"
                android:maxLines="1"
                android:textAppearance="@style/TextAppearance.Compat.Notification.Info"
                android:textColor="@color/gray_dark"
                android:textSize="@dimen/font_m"
                tools:text="Cause Description" />

            <TextView
                android:id="@+id/tx_date"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/space_xl"
                android:layout_weight="1"
                android:ellipsize="end"
                android:maxLines="1"
                android:textAppearance="@style/TextAppearance.Compat.Notification.Info"
                android:textColor="@color/gray_dark"
                android:textSize="@dimen/font_m"
                tools:text="Date" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:weightSum="2"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tx_cause_desc_notification"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/space_xl"
                android:ellipsize="end"
                android:textSize="@dimen/font_xl"
                android:textStyle="bold"
                android:maxLines="1"
                android:layout_weight="1"
                android:textAppearance="@style/TextAppearance.Compat.Notification.Info"
                tools:text="Turbine Trip" />

            <TextView
                android:id="@+id/tx_date_notification"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/space_xl"
                android:ellipsize="end"
                android:textSize="@dimen/font_xl"
                android:textStyle="bold"
                android:maxLines="1"
                android:layout_weight="1"
                android:textAppearance="@style/TextAppearance.Compat.Notification.Info"
                tools:text="10 Apr 2020" />

        </LinearLayout>


    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/notification_info"
        android:layout_centerInParent="true">

        <Button
            android:id="@+id/left_button"
            style="@style/Widget.Compat.NotificationActionContainer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="CLICK ME"
            android:textAppearance="@style/Widget.Compat.NotificationActionText"/>

        <Button
            android:id="@+id/right_button"
            style="@style/Widget.Compat.NotificationActionContainer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="CLICK ME"
            android:textAppearance="@style/Widget.Compat.NotificationActionText"/>
    </LinearLayout>

    <TextView
        android:id="@+id/timestamp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentTop="true"
        android:paddingEnd="3.5dp"
        android:paddingTop="8dp"
        android:textAppearance="@style/TextAppearance.Compat.Notification.Time"/>

</RelativeLayout>

Hal kecil yang perlu diketahui kenapa saya menggunakan widget dari AppCompat seperti AppCompatTextView atau AppCompatImageView misalnya, ini berhubungan dengan class RemoteView yang akan digunakan nanti, seperti disebutkan di dokumentasinya bahwa class ini hanya mendukung widget & layout yang terbatas :

RemoteViews is limited to support for the following layouts:

And the following widgets:

Descendants of these classes are not supported.

Dan jika anda menggunakan layout atau widget diluar yang telah disebutkan diatas maka akan menimbulkan error kurang lebih seperti ini :

Dan untuk tetap menerapkan beberapa style dari desain default text push notification dapat menggunakan android:textAppearance=”@style/TextAppearance.Compat.Notification….” yang sebelumnya pada API lama dapat menggunakan android:textAppearance=”@style/TextAppearance.AppCompat.Notification….”

2. Implementasi secara program

  • objek RemoteViews untuk meng-inflate custom layout :
val collapsedView = RemoteViews(packageName, R.layout.view_collapsed_notification)

val expandedView = RemoteViews(packageName, R.layout.view_expanded_notification)

  • set custom data (disini saya masih hardCode karena masih dummy dan belum akan diimplementasikan)
collapsedView.setTextViewText(
            R.id.timestamp,
            DateUtils.formatDateTime(this, System.currentTimeMillis(), DateUtils.FORMAT_SHOW_TIME))


expandedView.setTextViewText(
            R.id.timestamp,
            DateUtils.formatDateTime(this, System.currentTimeMillis(), DateUtils.FORMAT_SHOW_TIME))
        expandedView.setTextViewText(R.id.tx_title_notification, "PRE START UP - KMJ UNIT 4 TRIP")
        expandedView.setTextViewText(R.id.tx_cause_desc, "Cause Description")
        expandedView.setTextViewText(R.id.tx_date, "Date")
        expandedView.setTextViewText(R.id.tx_cause_desc_notification, "Turbine Trip")
        expandedView.setTextViewText(R.id.tx_date_notification, "10 Apr 2020")

  • adding action ke button
expandedView.setOnClickPendingIntent(
R.id.left_button,
PendingIntent.getActivity(this, 0, Intent(this, PreStartUpActivity::class.java), 0))

expandedView.setOnClickPendingIntent(
R.id.right_button,
PendingIntent.getActivity(this, 0, Intent(this, PreStartUpActivity::class.java), 0))

  • buat builder object
 val builder =
            Builder(this, NotificationGroup.UPLOAD.toValue().toString())
                .setSmallIcon(R.mipmap.ic_launcher1)
                .setContentTitle("Found a New Trip")
                .setContentText( "Expand to see the details")
                .setAutoCancel(true)
                .setContentIntent(
                    PendingIntent.getActivity(this, 0, Intent(this, MainActivity::class.java), 0))
                .setCustomContentView(collapsedView)
                .setCustomBigContentView(expandedView)
                .setStyle(DecoratedCustomViewStyle())

  • terakhir notificationManager untuk menerima push notification
val notificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(randomIdNotification, builder.build())

Tampilan setelah aplikasi dijalankan :

Akhir kata, CMIIW.

Rizky Agung Ramadhan has written 10 articles

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>