パッケージ、リポジトリ、アプリカテゴリを検索

easy_sidemenu のカバー
パッケージ詳細v1.0.0

easy_sidemenu

Flutter で使いやすく、ナビゲーションに使用できるサイドメニュー(ナビゲーションレール)

AndroidiOSWebmacOSWindowsLinux
30日間ダウンロード
2.1万
いいね数
459
Pub ポイント
160

パッケージをインストール

flutter pub add easy_sidemenu

パッケージ概要

公開情報に基づく選定ガイドです。参考としてご利用ください。

EasySideMenu は、応答性のあるナビゲーションインターフェースを構築するためのシンプルでカスタマイズ可能なサイドメニュー(ナビゲーションレール)を提供する Flutter パッケージです。Android、iOS、Web、macOS、Windows、Linux など複数のプラットフォームをサポートしています。使いやすさを重視した設計により、最小限のセットアップでナビゲーションレールを迅速に実装でき、デバイス間で一貫性がありアクセスしやすいナビゲーションを必要とするアプリに最適です。このパッケージは pub.dev を通じて Flutter プロジェクトにシームレスに統合できます。

用途

  • モバイルアプリのナビゲーション
  • Webダッシュボードレイアウト
  • デスクトップアプリケーションのナビゲーション
  • レスポンシブUIデザイン
  • クロスプラットフォームナビゲーション
  • カスタマイズ可能なサイドバー メニュー

主な機能

  • シンプルなAPI統合
  • レスポンシブレイアウトのサポート
  • カスタマイズ可能なメニュー項目
  • プラットフォームに依存しない設計
  • 組み込みアニメーション
  • ダークモードをサポートしています

適している対象

  • 初心者のFlutter開発者
  • クロスプラットフォームアプリビルダー
  • UI中心の開発者
  • ダッシュボードおよび管理パネル作成者
  • 一貫したナビゲーションを必要とするアプリ

注意事項

  • 基本的なスタイリングを超えるカスタマイズは限定的です
  • 複雑なデザインには追加のスタイリングが必要になる場合があります
  • 非常に大きなメニュー項目リストには最適化されていません
  • 更新のために外部のGitHubリポジトリに依存しています

元の README

関連するソースリポジトリの README 原文のスナップショットです。最新の内容はリポジトリをご覧ください。

Easy Sidemenu

logo

License Pub Version GitHub repo size

A highly customisable side navigation menu for Flutter. Supports Material 3 theming, glassmorphism, floating card panels, expansion items, badges, and responsive auto-collapse — with zero external dependencies.


Screenshots

Open Compact
Open Compact
Auto
Auto

Live demo

https://jamalianpour.github.io/easy_sidemenu


Getting started

Add the dependency:

dependencies:
  easy_sidemenu: ^1.0.0
import 'package:easy_sidemenu/easy_sidemenu.dart';

Basic usage

import 'package:easy_sidemenu/easy_sidemenu.dart';
import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _controller = SideMenuController();
  final _pageController = PageController();

  @override
  void initState() {
    super.initState();
    // Mirror selections to a PageView (or any router)
    _controller.addListener(() {
      _pageController.jumpToPage(_controller.currentIndex);
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: [
          SideMenu(
            controller: _controller,
            items: [
              SideMenuItem(
                title: 'Dashboard',
                icon: const Icon(Icons.dashboard_rounded),
                onTap: (index, controller) => controller.goTo(index),
              ),
              SideMenuItem(
                title: 'Settings',
                icon: const Icon(Icons.settings_rounded),
                onTap: (index, controller) => controller.goTo(index),
              ),
            ],
          ),
          Expanded(
            child: PageView(
              controller: _pageController,
              physics: const NeverScrollableScrollPhysics(),
              children: const [
                Center(child: Text('Dashboard')),
                Center(child: Text('Settings')),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Items

SideMenuItem
SideMenuItem(
  title: 'Dashboard',
  icon: const Icon(Icons.dashboard_rounded),
  // Optional badge overlaid on the icon
  badge: const Text('3', style: TextStyle(color: Colors.white, fontSize: 10)),
  // Tooltip shown in compact mode
  tooltipContent: 'Dashboard',
  // Widget shown at the trailing edge in open mode
  trailing: const Icon(Icons.chevron_right, size: 16),
  onTap: (index, controller) => controller.goTo(index),
),
Custom builder

Replace the default layout entirely for a single item:

SideMenuItem(
  builder: (context, displayMode) {
    return const Divider(height: 24, indent: 8, endIndent: 8);
  },
),
SideMenuExpansionItem
SideMenuExpansionItem(
  title: 'Projects',
  icon: const Icon(Icons.folder_rounded),
  initiallyExpanded: false,
  children: [
    SideMenuItem(
      title: 'Active',
      icon: const Icon(Icons.circle, size: 10),
      onTap: (index, controller) => controller.goTo(index),
    ),
    SideMenuItem(
      title: 'Archived',
      icon: const Icon(Icons.circle_outlined, size: 10),
      onTap: (index, controller) => controller.goTo(index),
    ),
  ],
),

Controller

SideMenuController extends ChangeNotifier:

final controller = SideMenuController(initialIndex: 0);

// Navigate to an item
controller.goTo(2);

// Read the current index
print(controller.currentIndex);

// Listen for changes
controller.addListener(() {
  print('Selected: ${controller.currentIndex}');
});

// Always dispose
controller.dispose();

Theming

SideMenuThemeData is a Material 3 ThemeExtension. Register it once for the whole app, or pass it directly to a single SideMenu.

App-wide (recommended)
MaterialApp(
  theme: ThemeData(
    colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
    useMaterial3: true,
    extensions: const [
      SideMenuThemeData(
        openWidth: 260,
        selectedColor: Color(0xFF2563EB),
        selectedIconColor: Colors.white,
        selectedTitleStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.w600),
      ),
    ],
  ),
)
Per-widget override
SideMenu(
  controller: controller,
  theme: const SideMenuThemeData(
    displayMode: SideMenuDisplayMode.compact,
    compactWidth: 72,
  ),
  items: [...],
)
SideMenuThemeData properties
Property Type Default Description
displayMode SideMenuDisplayMode auto auto / open / compact
openWidth double 300 Width in open mode
compactWidth double 70 Width in compact mode
collapseWidth double 600 Screen width at which auto switches to compact
menuDecoration BoxDecoration? null Full decoration for the menu container (overrides backgroundColor)
backdropSigma double? null Blur sigma for glassmorphism — wraps the menu in BackdropFilter
backgroundColor Color? ColorScheme.surface Menu background (ignored when menuDecoration is set)
selectedItemDecoration BoxDecoration? null Full decoration for the selected item (overrides selectedColor)
selectedColor Color? ColorScheme.primaryContainer Selected item highlight
hoverColor Color? onSurface 8% Hover highlight
selectedHoverColor Color? primaryContainer 80% Hover colour when item is also selected
selectedIconColor Color? ColorScheme.onPrimaryContainer Icon colour when selected
unselectedIconColor Color? ColorScheme.onSurfaceVariant Icon colour when unselected
iconSize double 24 Icon size
selectedTitleStyle TextStyle? labelLarge / onPrimaryContainer Title text style when selected
unselectedTitleStyle TextStyle? labelLarge / onSurfaceVariant Title text style when unselected
itemHeight double 50 Item row height
itemBorderRadius BorderRadius circular(8) Item corner radius
itemOuterPadding EdgeInsetsGeometry symmetric(h: 5) Padding around each item
itemInnerSpacing double 8 Spacing between icon and title
showTooltip bool true Show item title as tooltip in compact mode
showHamburger bool false Show a hamburger button that collapses the menu
toggleColor Color? onSurfaceVariant Expand/collapse toggle icon colour
expansionArrowColor Color? onSurfaceVariant Expansion arrow in collapsed state
expansionArrowOpenColor Color? ColorScheme.primary Expansion arrow in open state
SideMenu properties
Property Type Default Description
controller SideMenuController required Manages the selected index
items List<SideMenuItemBase> required Items to display
theme SideMenuThemeData? null Per-widget theme override
title Widget? null Widget shown above items
footer Widget? null Widget pinned to the bottom
alwaysShowFooter bool false Keep footer visible in compact mode
showToggle bool false Show collapse/expand toggle button
collapseWidth double 600 Screen width threshold for auto mode
displayModeToggleDuration Duration 350 ms Open ↔ compact animation duration
onDisplayModeChanged ValueChanged<SideMenuDisplayMode>? null Called when display mode changes

Advanced customisation

Gradient sidebar
SideMenu(
  controller: controller,
  theme: const SideMenuThemeData(
    menuDecoration: BoxDecoration(
      gradient: LinearGradient(
        colors: [Color(0xFF667EEA), Color(0xFF764BA2)],
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
      ),
    ),
    selectedColor: Color(0x33FFFFFF),
    selectedIconColor: Colors.white,
  ),
  items: [...],
)
Left-border selected indicator (Minimal style)
SideMenu(
  controller: controller,
  theme: const SideMenuThemeData(
    selectedItemDecoration: BoxDecoration(
      color: Color(0xFFEFF6FF),
      border: Border(left: BorderSide(color: Color(0xFF2563EB), width: 3)),
    ),
    itemBorderRadius: BorderRadius.zero,
    itemOuterPadding: EdgeInsets.zero,
  ),
  items: [...],
)
Glassmorphism

Requires a backdropSigma and a semi-transparent menuDecoration. Place the SideMenu inside a widget that has a visible background (image, gradient) behind it.

// 1. Wrap the whole layout in a gradient container
Container(
  decoration: const BoxDecoration(
    gradient: LinearGradient(
      colors: [Color(0xFF1A1A2E), Color(0xFF0F3460)],
    ),
  ),
  child: Row(
    children: [
      // 2. The SideMenu renders as a frosted panel
      SideMenu(
        controller: controller,
        theme: SideMenuThemeData(
          backdropSigma: 18,
          menuDecoration: BoxDecoration(
            color: Colors.white.withValues(alpha: 0.15),
            border: Border(
              right: BorderSide(color: Colors.white.withValues(alpha: 0.25)),
            ),
          ),
          selectedIconColor: Colors.white,
          unselectedIconColor: Colors.white70,
        ),
        items: [...],
      ),
      Expanded(child: ...),
    ],
  ),
)
Floating card (rounded + shadow)

Wrap the SideMenu in a Padding and set menuDecoration with a borderRadius and boxShadow:

Row(
  children: [
    Padding(
      padding: const EdgeInsets.all(8),
      child: SideMenu(
        controller: controller,
        theme: SideMenuThemeData(
          menuDecoration: BoxDecoration(
            color: Colors.white,
            borderRadius: const BorderRadius.all(Radius.circular(16)),
            border: Border.all(color: const Color(0xFFE2E8F0)),
            boxShadow: [
              BoxShadow(
                color: Colors.black.withValues(alpha: 0.08),
                blurRadius: 24,
                offset: const Offset(4, 0),
              ),
            ],
          ),
        ),
        items: [...],
      ),
    ),
    Expanded(child: ...),
  ],
)

Migrating from v0.7

See MIGRATION.md for a complete before/after guide covering every breaking change.

Quick summary:

v0.7 v1.0
SideMenuStyle(...) SideMenuThemeData(...)
style: param on SideMenu theme: param on SideMenu
openSideMenuWidth openWidth
compactSideMenuWidth compactWidth
controller.changePage(i) controller.goTo(i)
controller.currentPage controller.currentIndex
controller.addListener((i) {...}) controller.addListener(() { use controller.currentIndex })
SideMenuItemType SideMenuItemBase
badgeContent: badge:
initialExpanded: initiallyExpanded:

Contributing

Issues and pull requests are welcome on GitHub.


License

MIT — see LICENSE for details.

カテゴリー

ソースリポジトリ

このパッケージを使用しているプロジェクト