Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีสร้าง Custom Notification Layout และสีข้อความใน Android

ตัวอย่างนี้สาธิตวิธีสร้าง 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 และสีที่กำหนดเอง

วิธีสร้าง Custom Notification Layout และสีข้อความใน Android