Drawer (Navigation Drawer) คือแผงโต้ตอบที่เลื่อนออกมาจากขอบซ้าย (หรือขวา) ของหน้าจอและแสดงลิงก์นำทาง บน Android ใช้งานผ่าน DrawerLayout บน iOS — ผ่านโซลูชันแบบกำหนดเองเช่น SideMenu หรือ UISplitViewController มาตรฐานบน iPad อ่านเพิ่มเติมเกี่ยวกับข้อมูลจำเพาะได้ที่ เอกสาร Material Design 3
ประเด็นสำคัญ
Drawer (Navigation Drawer) คือองค์ประกอบนำทางในรูปแบบแผงที่เลื่อนออกจากขอบซ้ายของหน้าจอโดยการปัดหรือแตะไอคอนแฮมเบอร์เกอร์ (สามเส้นแนวนอน) Drawer ประกอบด้วยลิงก์นำทาง ส่วนหัว และองค์ประกอบเสริม: รูปประจำตัวผู้ใช้ ป้ายการแจ้งเตือน ตัวแบ่ง แผงสามารถซ้อนทับเนื้อหา (Modal) หรือเลื่อนเนื้อหา (Standard)
Material Design 3 (2026) กำหนดให้ Navigation Drawer เป็นคอมโพเนนต์สำหรับแอปที่มีรายการนำทาง 6+ รายการ ต่างจาก Bottom Navigation ตรงที่ Drawer ไม่ใช้พื้นที่หน้าจอถาวรและจะแสดงเมื่อผู้ใช้ร้องขอเท่านั้น ซึ่งช่วยเพิ่มพื้นที่สำหรับเนื้อหาแต่ต้องมีการดำเนินการเพิ่มเติมเพื่อเปิด Google แนะนำ Drawer สำหรับแอปที่มีลำดับชั้นส่วนลึก
การวิจัยของ UX Planet (2025) แสดงให้เห็นว่า: Drawer เหมาะสำหรับแอปที่มี 5–15 ส่วน แต่เวลาในการนำทางสูงกว่า Bottom Navigation ถึง 40% ผู้ใช้พลาดรายการเมนูที่อยู่ต่ำกว่ารอยพับหน้าจอ (เลื่อน) ดังนั้นส่วนสำคัญควรอยู่ที่ด้านบนของ Drawer และส่วนที่สำคัญน้อยกว่า (เกี่ยวกับแอป การตั้งค่า) อยู่ด้านล่าง คั่นด้วยตัวแบ่ง
Modal Drawer เลื่อนทับเนื้อหา ทำให้พื้นหลังมืดลง ใช้บนอุปกรณ์มือถือที่ความกว้างหน้าจอจำกัด หลังจากเลือกรายการ Drawer จะปิดโดยอัตโนมัติ Standard Drawer (Permanent) คือแผงคงที่ที่มองเห็นได้ตลอดเวลา เลื่อนเนื้อหา ใช้บนแท็บเล็ตและเดสก์ท็อปที่มีความกว้างหน้าจอตั้งแต่ 900 dp Material 3 ยังกำหนด Rail Drawer — เวอร์ชันกะทัดรัดสำหรับแท็บเล็ตที่แสดงเฉพาะไอคอน
| ประเภท | พฤติกรรม | การใช้งาน |
|---|---|---|
| Modal | ซ้อนทับเนื้อหา ทำให้พื้นหลังมืดลง | โทรศัพท์ การนำทางชั่วคราว |
| Standard | เลื่อนเนื้อหา คงที่ | แท็บเล็ต เดสก์ท็อป (900+ dp) |
| Rail | แผงด้านข้างกะทัดรัดพร้อมไอคอน | แท็บเล็ต การนำทางแบบปรับตัว |
DrawerLayout คือ ViewGroup มาตรฐานใน Android ที่สร้างเมนูด้านข้างแบบเลื่อน DrawerLayout ประกอบด้วยองค์ประกอบย่อยสองส่วน: ส่วนแรก — เนื้อหาหลัก (FrameLayout กับ NavHostFragment) ส่วนที่สอง — NavigationView พร้อมเมนู DrawerLayout จัดการท่าทางการปัดและการเปิด/ปิดโดยโปรแกรมผ่าน ActionBarDrawerToggle
// กิจกรรมด้วย DrawerLayout และ NavigationView
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var drawerLayout: DrawerLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
drawerLayout = binding.drawerLayout
val navView = binding.navView
val navController = findNavController(R.id.nav_host_fragment)
// การเชื่อมโยง Drawer กับ Navigation Component
NavigationUI.setupActionBarWithNavController(
this, navController, drawerLayout
)
NavigationUI.setupWithNavController(navView, navController)
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(
findNavController(R.id.nav_host_fragment),
drawerLayout
)
}
}
// XML: activity_main.xml
// <androidx.drawerlayout.widget.DrawerLayout
// android:id="@+id/drawerLayout"
// ...>
// <!-- เนื้อหาหลัก -->
// <FrameLayout android:id="@+id/nav_host_fragment"
// android:layout_width="match_parent"
// android:layout_height="match_parent" />
// <!-- Navigation Drawer -->
// <com.google.android.material.navigation.NavigationView
// android:id="@+id/navView"
// android:layout_width="wrap_content"
// android:layout_height="match_parent"
// android:layout_gravity="start"
// app:menu="@menu/nav_menu" />
// </androidx.drawerlayout.widget.DrawerLayout>NavigationView คือคอมโพเนนต์ Material Design สำหรับเนื้อหา Drawer รองรับส่วนหัว (headerLayout) รายการเมนู (menu) หัวข้อย่อย ช่องทำเครื่องหมายและสวิตช์ แอตทริบิวต์ app:menu ชี้ไปยังเมนู XML ที่มีรายการนำทาง NavigationUI จะไฮไลต์รายการที่ใช้งานอยู่โดยอัตโนมัติและซิงค์สถานะกับ NavController
iOS ไม่มีคอมโพเนนต์ "Drawer" ในตัว — Apple ไม่แนะนำเมนูด้านข้างสำหรับ iPhone (HIG, 2026) อย่างไรก็ตาม สำหรับ iPad จะใช้ UISplitViewController พร้อมแผงหลักและแผงรอง สำหรับ iPhone เมนูด้านข้างจะใช้งานผ่านไลบรารีของบุคคลที่สาม (SideMenu, SwiftUI-side-menu) หรือโซลูชันแบบกำหนดเองพร้อมออฟเซ็ตเนื้อหา ใน SwiftUI เมนูด้านข้างถูกสร้างขึ้นผ่าน ZStack พร้อมแอนิเมชันออฟเซ็ต
import SwiftUI
struct DrawerView<Content: View, Menu: View>: View {
let menuWidth: CGFloat = 280
@Binding var isOpen: Bool
@ViewBuilder let content: Content
@ViewBuilder let menu: Menu
var body: some View {
ZStack(alignment: .leading) {
content
.offset(x: isOpen ? menuWidth : 0)
.animation(.easeInOut, value: isOpen)
if isOpen {
menu
.frame(width: menuWidth)
.transition(.move(edge: .leading))
Color.black.opacity(0.3)
.ignoresSafeArea()
.onTapGesture { isOpen = false }
}
}
}
}
// การใช้งาน
struct ContentView: View {
@State private var showDrawer = false
var body: some View {
DrawerView(isOpen: $showDrawer) {
NavigationStack {
HomeView()
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: { showDrawer.toggle() }) {
Image(systemName: "line.horizontal.3")
}
}
}
}
} menu: {
DrawerMenuView()
}
}
}สำหรับโปรเจกต์ iOS ที่ใช้งานจริง มักใช้ไลบรารี SideMenu (GitHub, 8k+ ดาว) โดยให้ UIViewController ที่พร้อมใช้งานพร้อมรองรับท่าทาง การเบลอพื้นหลัง ความกว้างที่กำหนดเองและแอนิเมชัน SideMenu รองรับเมนูซ้ายและขวา หลายระดับและการผสานรวม UIKit ผ่าน UINavigationController ทางเลือกคือ UISplitViewController บน iPad (ระบบ ไม่มีแอนิเมชันแบบกำหนดเอง)
Drawer อนุญาตให้ปรับแต่งได้อย่างกว้างขวาง ใน Android NavigationView รองรับ headerLayout — เค้าโครงแบบกำหนดเองที่วางเหนือรายการเมนู สามารถมีรูปประจำตัว ชื่อผู้ใช้ อีเมลและรูปปก รายการเมนูจะถูกจัดกลุ่มผ่าน <menu> พร้อมหัวข้อย่อย ตัวแบ่งและสวิตช์ บน iOS การปรับแต่ง SideMenu รวมถึงการตั้งค่าสีพื้นหลัง การเบลอ ความกว้างและรัศมีมุม
// ส่วนหัวแบบกำหนดเองสำหรับ NavigationView
val headerView = binding.navView.inflateHeaderView(R.layout.nav_header)
headerView.findViewById<ImageView>(R.id.iv_avatar)
.setImageResource(R.drawable.avatar)
headerView.findViewById<TextView>(R.id.tv_name)
.text = "John Doe"
// การกำหนดค่ารายการเมนู
val menuItem = binding.navView.menu.findItem(R.id.nav_notifications)
menuItem.isChecked = true
// การเพิ่มป้าย
val badge = binding.navView.getOrCreateBadge(R.id.nav_notifications)
badge.number = 15
badge.isVisible = trueMaterial Design แนะนำโครงสร้าง Drawer ดังนี้: ส่วนหัว (ชื่อ รูปประจำตัว) รายการนำทางหลัก (5–8) ตัวแบ่ง รายการรอง (การตั้งค่า ความช่วยเหลือ) ส่วนท้าย (เกี่ยวกับแอป เวอร์ชัน) ใน Material 3 NavigationView ยังรองรับการไฮไลต์รายการที่ใช้งานแบบกำหนดเองผ่าน itemShape และ itemBackground
Drawer มีประสิทธิภาพสำหรับแอปที่มี 6+ ส่วน การตั้งค่าและหน้าช่วยเหลือ ไม่เหมาะสำหรับแอปที่ต้องการการเข้าถึงส่วนต่าง ๆ อย่างรวดเร็ว — ในกรณีดังกล่าว Bottom Navigation จะดีกว่า Material Design แนะนำให้รวม Drawer กับ Bottom Navigation: การนำทางหลัก — Bottom (3–5 แท็บ) เพิ่มเติม — Drawer (การตั้งค่า ความช่วยเหลือ เกี่ยวกับแอป)
ข้อผิดพลาดทั่วไปเมื่อใช้งาน Drawer: เมนูที่มากเกินไป (15+ รายการไม่มีการจัดกลุ่ม) ซ่อนส่วนสำคัญใต้รอยพับ ไม่มีไอคอน (ข้อความที่ไม่มีไอคอนสแกนช้ากว่า 30%) แอนิเมชันที่มีความล่าช้า (ควร ≤ 200 ms) แนวทางปฏิบัติที่ดีที่สุด: ส่วนหัวพร้อมชื่อผู้ใช้ ไอคอนสำหรับทุกรายการ ตัวแบ่งระหว่างกลุ่ม การไฮไลต์ส่วนที่ใช้งาน การรองรับท่าทางการปัดเพื่อเปิด
คำถามที่พบบ่อย
Drawer คือเมนูด้านข้างที่ซ่อนอยู่ซึ่งเปิดด้วยท่าทาง เหมาะสำหรับ 6+ ส่วนและลำดับชั้นลึก Bottom Navigation คือแถบด้านล่างที่มองเห็นได้ตลอดเวลาสำหรับ 3–5 ส่วน Drawer ประหยัดพื้นที่หน้าจอแต่ต้องดำเนินการเพิ่มเติมเพื่อเปิด ทำให้เวลาในการนำทางเพิ่มขึ้น 40%
SwiftUI ไม่มี Drawer ในตัว ใช้ ZStack พร้อมออฟเซ็ตเนื้อหาและแอนิเมชันดังตัวอย่างด้านบน สำหรับการใช้งานจริง ใช้ไลบรารี: SideMenu (Swift Package) หรือตัวห่อแบบกำหนดเองรอบ UISplitViewController บน iPad ใช้ UISplitViewController ด้วย preferredDisplayMode .oneBesideSecondary
Apple HIG (2026) ระบุว่า: เมนูด้านข้างซ่อนเนื้อหาและละเมิดหลักการจัดการโดยตรง iOS แนะนำ Tab Bar สำหรับการนำทาง Drawer บน iPhone ใช้สำหรับการตั้งค่าและการดำเนินการเพิ่มเติมเท่านั้น ไม่ใช่สำหรับการนำทางหลัก บน iPad Drawer จะถูกแทนที่ด้วย UISplitViewController ซึ่งเป็นมาตรฐานของระบบ
ใน Android DrawerLayout จัดการการปัดจากขอบซ้ายโดยอัตโนมัติ ใน iOS Drawer แบบกำหนดเองต้องใช้ UIPanGestureRecognizer หรือ Edge Pan Gesture (SwiftUI — .gesture กับ DragGesture) สำคัญ: การปัดต้องขัดแย้งกับท่าทาง "กลับ" ของระบบ — บน iOS ขอบซ้ายถูกครอบครองโดยท่าทางของระบบ
ได้ ใน Android ระบุ android:layout_gravity="end" สำหรับ NavigationView บน iOS สร้างเมนูด้วย edge: .trailing Drawer ด้านขวาใช้น้อยกว่า — สำหรับตัวเลือกเพิ่มเติม ตัวกรองหรือแชท การนำทางหลักยังคงอยู่ทางซ้ายตาม Material Design และความคาดหวังของผู้ใช้
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ