ตัวอย่างนี้สาธิตวิธี ปรับแต่ง Overflow Menu (สามจุด) ใน Toolbar รวมถึงการเปลี่ยน Icon, ซ่อน/แสดง Menu Item แบบไดนามิก
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
Android Studio → New Project → Empty Activity (Theme: MaterialComponents)
ขั้นตอนที่ 2: Layout (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.MaterialComponents.Light" />
</LinearLayout>
ขั้นตอนที่ 3: Menu Resource (res/menu/main_menu.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/menu_bluetooth"
android:icon="@drawable/ic_bluetooth"
android:title="Bluetooth"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_call"
android:icon="@drawable/ic_call"
android:title="Call"
app:showAsAction="ifRoom|collapseActionView" />
<item
android:id="@+id/menu_chat"
android:icon="@drawable/ic_chat"
android:title="Chat"
android:visible="false"
app:showAsAction="ifRoom|collapseActionView" />
<item
android:id="@+id/menu_about"
android:title="About"
app:showAsAction="never" />
</menu>
ขั้นตอนที่ 4: โค้ดหลัก (MainActivity.kt)
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.widget.Toolbar
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
class MainActivity : AppCompatActivity() {
private lateinit var toolbar: Toolbar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "Toolbar Menu Demo"
toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
// 🔑 เปลี่ยน Overflow Icon (สามจุด) แบบโปรแกรมมัติ
// ต้องทำหลัง setSupportActionBar
val overflowIcon = ContextCompat.getDrawable(this, R.drawable.ic_custom_overflow)
overflowIcon?.let { toolbar.setOverflowIcon(it) }
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_bluetooth -> {
Toast.makeText(this, "Bluetooth clicked", Toast.LENGTH_SHORT).show()
true
}
R.id.menu_call -> {
Toast.makeText(this, "Call clicked", Toast.LENGTH_SHORT).show()
true
}
R.id.menu_chat -> {
Toast.makeText(this, "Chat clicked", Toast.LENGTH_SHORT).show()
true
}
R.id.menu_about -> {
Toast.makeText(this, "About clicked", Toast.LENGTH_SHORT).show()
true
}
else -> super.onOptionsItemSelected(item)
}
}
// 🔑 จุดสำคัญ: ปรับ Menu แบบไดนามิก (ซ่อน/แสดง/เปลี่ยน Icon)
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
// เรียกทุกครั้งก่อน Menu แสดง
val callItem = menu.findItem(R.id.menu_call)
val chatItem = menu.findItem(R.id.menu_chat)
// ตัวอย่าง: สลับการแสดง Call/Chat
callItem.isVisible = false
chatItem.isVisible = true
// เปลี่ยน Icon ของ Bluetooth
val btItem = menu.findItem(R.id.menu_bluetooth)
btItem.icon = ContextCompat.getDrawable(this, R.drawable.ic_bluetooth_connected)
return super.onPrepareOptionsMenu(menu)
}
}
🎨 เปลี่ยน Overflow Icon ผ่าน Theme (XML) - วิธีมาตรฐาน
<!-- res/values/styles.xml -->
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="actionOverflowButtonStyle">@style/CustomOverflow</item>
</style>
<style name="CustomOverflow" parent="Widget.AppCompat.ActionButton.Overflow">
<item name="android:src">@drawable/ic_custom_overflow</item>
</style>
🔧 Vector Drawable สำหรับ Overflow Icon (res/drawable/ic_custom_overflow.xml)
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="https://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,16c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4s4,1.79 4,4s-1.79,4 -4,4zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2s2,-0.9 2,-2s-0.9,-2 -2,-2zM12,4c-1.1,0 -2,0.9 -2,2s0.9,2 2,2s2,-0.9 2,-2s-0.9,-2 -2,-2z" />
</vector>
💡 เคล็ดลับเพิ่มเติม
app:showAsAction="ifRoom": แสดงใน Toolbar ถ้ามีที่, ไม่งั้นไป Overflowapp:showAsAction="never": บังคับให้อยู่ใน Overflow เท่านั้นapp:showAsAction="always": บังคับแสดงใน Toolbar (อาจทับกัน)collapseActionView: ใช้กับ SearchView, Custom View- ใช้
menu.findItem(id).setVisible(false)ซ่อน Item - ใช้
menu.findItem(id).icon = newDrawableเปลี่ยน Icon
ขั้นตอนที่ 5: AndroidManifest.xml
Manifest มาตรฐาน (Theme ตั้งใน Application/Activity)
ทดสอบ
- รันแอป → Toolbar แสดง Icon Bluetooth, Overflow Icon เป็น Custom
- กด Overflow (สามจุด) → เมนูแสดง About (Chat ซ่อน, Call ซ่อน)
- กด About → Toast แสดง