ตัวอย่างนี้สาธิตวิธีสร้าง Custom Notification Layout แบบกำหนดเอง พร้อมควบคุมสีข้อความ รูปภาพ และ Layout เองทั้งหมด โดยใช้ RemoteViews และ NotificationCompat.Builder
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
เปิด Android Studio ไปที่ File → New Project
ขั้นตอนที่ 2: Layout หลัก (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Custom Notification Demo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
ขั้นตอนที่ 3: MainActivity.java - สร้าง Notification แบบปกติและ Custom
package com.app.sample;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RemoteViews;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notification_main); // Layout ที่มี 2 ปุ่ม
Button btnNormal = findViewById(R.id.notification);
Button btnCustom = findViewById(R.id.customnotification);
btnNormal.setOnClickListener(v -> showNormalNotification());
btnCustom.setOnClickListener(v -> showCustomNotification());
}
// Notification แบบปกติ (Standard)
private void showNormalNotification() {
String title = getString(R.string.notification_title);
String text = getString(R.string.notification_text);
Intent intent = new Intent(this, NotificationView.class);
intent.putExtra("title", title);
intent.putExtra("text", text);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default_channel")
.setSmallIcon(R.drawable.logo_small)
.setTicker(getString(R.string.notification_ticker))
.setContentTitle(title)
.setContentText(text)
.addAction(R.drawable.ic_launcher, "Action", pIntent)
.setContentIntent(pIntent)
.setAutoCancel(true);
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(1, builder.build());
}
// Custom Notification Layout
private void showCustomNotification() {
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.custom_notification);
String title = getString(R.string.custom_notification_title);
String text = getString(R.string.custom_notification_text);
Intent intent = new Intent(this, NotificationView.class);
intent.putExtra("title", title);
intent.putExtra("text", text);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default_channel")
.setSmallIcon(R.drawable.logo_small)
.setTicker(getString(R.string.custom_notification_ticker))
.setAutoCancel(true)
.setContentIntent(pIntent)
.setContent(remoteViews); // ใช้ Custom Layout
// ตั้งค่า View ใน Custom Layout
remoteViews.setImageViewResource(R.id.image_left, R.drawable.ic_launcher);
remoteViews.setImageViewResource(R.id.image_right, R.drawable.android_happy);
remoteViews.setTextViewText(R.id.title, title);
remoteViews.setTextViewText(R.id.text, text);
// ตั้งค่าสีข้อความ (ต้องใช้ setTextColor บน RemoteViews API 23+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
remoteViews.setTextColor(R.id.title, Color.RED);
remoteViews.setTextColor(R.id.text, Color.BLUE);
}
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(2, builder.build());
}
}
ขั้นตอนที่ 4: Custom Notification Layout (custom_notification.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<ImageView
android:id="@+id/image_left"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/image_left"
android:layout_marginStart="16dp"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#FF0000" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/image_left"
android:layout_below="@id/title"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:textSize="14sp"
android:textColor="#0000FF" />
<ImageView
android:id="@+id/image_right"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:padding="8dp"
android:src="@drawable/android_happy" />
</RelativeLayout>
ขั้นตอนที่ 5: Layout ปุ่มหลัก (notification_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<Button
android:id="@+id/notification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Standard Notification" />
<Button
android:id="@+id/customnotification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/notification"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="Custom Notification" />
</RelativeLayout>
ขั้นตอนที่ 6: Notification View Activity (NotificationView.java)
package com.app.sample;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class NotificationView extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notification_view);
TextView lblTitle = findViewById(R.id.lbl_title);
TextView lblText = findViewById(R.id.lbl_text);
TextView title = findViewById(R.id.title);
TextView text = findViewById(R.id.text);
String titleStr = getIntent().getStringExtra("title");
String textStr = getIntent().getStringExtra("text");
title.setText(titleStr);
text.setText(textStr);
}
}
ขั้นตอนที่ 7: Notification View Layout (notification_view.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<TextView
android:id="@+id/lbl_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title:"
android:textStyle="bold" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/lbl_title"
android:layout_marginStart="8dp" />
<TextView
android:id="@+id/lbl_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/lbl_title"
android:text="Text:"
android:textStyle="bold" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_toEndOf="@id/lbl_text"
android:layout_marginStart="8dp" />
</RelativeLayout>
ขั้นตอนที่ 8: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.app.sample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".NotificationView" />
</application>
</manifest>
เคล็ดลับ Custom Notification:
- ใช้
RemoteViewsเพื่อควบคุม View ใน Notification - รองรับ View พื้นฐาน: TextView, ImageView, ProgressBar, Chronometer, Button
- ไม่รองรับ ViewGroup ซ้อนกันมาก, WebView, EditText (interactive)
- ตั้งค่าสีข้อความด้วย
remoteViews.setTextColor(viewId, color)(API 23+) - สำหรับ Android 8.0+ ต้องสร้าง Notification Channel
- ขนาดสูงสุด Custom Layout ประมาณ 256dp height
การทดสอบ
รันแอป กดปุ่ม "Custom Notification" จะแสดง Notification พร้อม Layout และสีที่กำหนดเอง
