Drawer(Navigation Drawer)は、画面の左(または右)端からスライドして表示されるインタラクティブなパネルで、ナビゲーションリンクを表示します。AndroidではDrawerLayout、iOSではSideMenuのようなカスタムソリューションまたはiPadの標準UISplitViewControllerを介して実装されます。仕様の詳細はMaterial Design 3ドキュメントをご覧ください。
重要なポイント
Drawer(Navigation Drawer)は、スワイプジェスチャーまたはハンバーガーアイコン(3本の水平線)のタップで画面の左端からスライドするパネル形式のナビゲーション要素です。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は、スライド式サイドメニューを実装するAndroidの標準ViewGroupです。DrawerLayoutには2つの子要素があります:1つ目はメインコンテンツ(NavHostFragmentを持つFrameLayout)、2つ目はメニューを持つ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)
// Navigation ComponentへのDrawerのバインド
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は、Drawerコンテンツ用のMaterial Designコンポーネントです。ヘッダー(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は左右のメニュー、複数レベル、UINavigationControllerを介したUIKit統合をサポートします。代替手段はiPadのUISplitViewController(システム標準、カスタムアニメーションなし)です。
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では、preferredDisplayMode .oneBesideSecondaryのUISplitViewControllerを使用してください。
Apple HIG(2026)は、サイドメニューがコンテンツを隠し、直接操作の原則に違反すると述べています。iOSはナビゲーションにTab Barを推奨しています。iPhoneのDrawerは、メインナビゲーションではなく、設定や追加アクションにのみ使用されます。iPadでは、Drawerはシステム標準のUISplitViewControllerに置き換えられます。
Androidでは、DrawerLayoutが左端からのスワイプを自動的に処理します。iOSでは、カスタムDrawerにUIPanGestureRecognizerまたはEdge Pan Gesture(SwiftUI — DragGesture付き.gesture)が必要です。重要:スワイプはシステムの「戻る」ジェスチャーと競合する必要があります—iOSでは左端はシステムジェスチャーで占められています。
はい。Androidでは、NavigationViewにandroid:layout_gravity="end"を指定します。iOSでは、edge: .trailingのメニューを作成します。右側のDrawerはあまり使用されません—追加オプション、フィルター、チャット用です。メインナビゲーションは、Material Designとユーザーの期待に従って左側に残ります。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。