ภาพรวม
บทความนี้ซ้ำกับ ID 1004061564 สาธิตการสร้าง Badge Count บน Toolbar/ActionBar โดยใช้ Custom Layout ใน Toolbar
โค้ดสำคัญ (รูปแบบทันสมัย)
Menu-based Approach (แนะนำ)
แทนที่จะ Hard-code ใน Layout ให้ใช้ Menu Item พร้อม ActionView:
res/menu/menu_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_notifications"
android:icon="@drawable/ic_notifications"
android:title="Notifications"
app:actionLayout="@layout/badge_layout"
app:showAsAction="always" />
</menu>
res/layout/badge_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="16dp">
<ImageView
android:id="@+id/ivNotificationIcon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerVertical="true"
android:src="@drawable/ic_notifications" />
<TextView
android:id="@+id/tvBadgeCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/ivNotificationIcon"
android:layout_alignEnd="@id/ivNotificationIcon"
android:background="@drawable/badge_background"
android:text="0"
android:textColor="@android:color/white"
android:textSize="10sp"
android:textStyle="bold"
android:minWidth="16dp"
android:minHeight="16dp"
android:gravity="center"
android:paddingHorizontal="4dp"
android:visibility="gone" />
</RelativeLayout>
res/drawable/badge_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="https://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#FF0000" />
<stroke android:width="1dp" android:color="@android:color/white" />
</shape>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView tvBadgeCount;
private int notificationCount = 0;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
// หา View จาก ActionView
MenuItem item = menu.findItem(R.id.action_notifications);
View actionView = item.getActionView();
if (actionView != null) {
tvBadgeCount = actionView.findViewById(R.id.tvBadgeCount);
updateBadge();
}
return true;
}
private void createNotification() {
// ... สร้าง Notification ตามปกติ ...
notificationCount++;
updateBadge();
}
private void updateBadge() {
if (tvBadgeCount != null) {
if (notificationCount > 0) {
tvBadgeCount.setVisibility(View.VISIBLE);
tvBadgeCount.setText(notificationCount > 99 ? "99+" : String.valueOf(notificationCount));
} else {
tvBadgeCount.setVisibility(View.GONE);
}
}
}
}
เปรียบเทียบวิธีการ
| วิธี | ข้อดี | ข้อเสีย |
|---|---|---|
| Hard-coded Toolbar Layout | ควบคุม UI ได้เต็มที่ | ซับซ้อน, ไม่รองรับ Menu ปกติ |
| Menu + ActionView | มาตรฐาน, รองรับ Overflow, Theming | ต้อง inflate เอง |
| Notification Badge (System) | อัตโนมัติ, ไม่ต้องโค้ด | ควบคุมรายละเอียดไม่ได้ |
| ShortcutBadger Library | รองรับ Launcher หลายตัว | ขึ้นกับ Library ภายนอก |
แนวทางปฏิบัติที่ดี
- ใช้ Menu + ActionView เป็นหลัก
- ซ่อน Badge เมื่อเป็น 0
- จำกัดตัวเลขสูงสุด (99+)
- Sync Count กับ Notification จริง (ลบเมื่อ dismiss)
- ใช้ WorkManager/Service อัปเดต Badge เมื่อแอปไม่ได้รัน