motionx 0.1.1 copy "motionx: ^0.1.1" to clipboard
motionx: ^0.1.1 copied to clipboard

A modern, highly customizable Flutter bottom navigation bar with floating indicators, smooth animations, badges, PageView synchronization, and extensible APIs.

MotionX #

A high-performance, fluid, and customizable navigation bar framework for Flutter featuring unified indicator physics, smooth Bezier notch cutouts, and flexible badge architecture.

pub package Flutter Dart License: MIT Likes


Overview #

MotionX is designed to modernize bottom navigation in Flutter applications. Standard navigation components often suffer from rigid layouts, limited indicator shapes, or abrupt state transitions. MotionX addresses these limitations with a single frame-synchronized rendering architecture that computes floating indicator translation and background notch cutout geometry continuously from a single offset driver (animationOffset).

Key Architectural Pillars:

  • Modern Design Language: Built ground-up to support elevated floating circles, background capsules, top pill bars, bottom underline strips, and custom geometry.
  • Continuous Frame Synchronization: Synchronizes floating indicators and background notch cutouts frame-by-frame during user drag gestures and programmatic animations.
  • Granular Customization: Complete control over shapes, proportional scaling, depth, Bezier shoulder radii, haptics, and padding.
  • Flexible Badge Engine: Positioning system supporting preset anchors, pixel-precise offsets, follow-motion toggles, and customizable container/content metrics.
  • Decoupled Controller Architecture: First-class integration with PageController and TabController for synchronized PageView dragging without layout recalculations.
  • Production Accessibility: Complete Right-to-Left (RTL) localization support, screen-reader semantics tags, and Material 3 compliance.

Preview #

[MotionX Preview]


Features #

  • ✅ Floating Indicators: Elevated circular FAB, background capsule card, top accent pill, and bottom underline strip.
  • ✅ Proportional indicatorSize Scaling: Automatically scales widths, heights, and thickness across all built-in indicator shapes.
  • ✅ 2D Bezier Notch Geometry: Smooth Bezier cutouts (SmoothNotchShape) and classic circular arc cutouts (ClassicNotchShape) with customizable cradle depth.
  • ✅ Persistent Docked Cutout: Background notch cutout remains permanently visible framing the active indicator at rest, during dragging, and after settling.
  • ✅ Flexible Badge Positioning: Position badges using preset alignment anchors (topRight, topLeft, bottomRight, bottomLeft, topCenter) or custom Offset(dx, dy) vectors.
  • ✅ Decoupled Badge Opacity: Badges remain 100% visible on selected and unselected tabs with optional followIndicator motion lift.
  • ✅ PageView & TabController Sync: Single continuous animation value binding for gesture dragging without position jumps.
  • ✅ Navigation Guards (onTabWillChange): Asynchronous interceptors for tab switching validation (e.g. form confirmation modals).
  • ✅ Right-to-Left (RTL) Support: Automatic directionality inversion for internationalized applications.
  • ✅ Accessible Semantics: Accessible button semantics, selected state flags, and custom semantic labels.

Installation #

Add motionx to your pubspec.yaml dependencies:

dependencies:
  motionx: ^0.1.0

Then run:

flutter pub get

Quick Start #

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

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

  @override
  State<QuickStartExample> createState() => _QuickStartExampleState();
}

class _QuickStartExampleState extends State<QuickStartExample> {
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('Active Tab Index: $_currentIndex'),
      ),
      bottomNavigationBar: MotionXNavigationBar(
        index: _currentIndex,
        onTabSelected: (index) => setState(() => _currentIndex = index),
        items: const [
          MotionXItem(label: 'Explore', icon: Icon(Icons.explore_outlined)),
          MotionXItem(label: 'Messages', icon: Icon(Icons.chat_bubble_outline)),
          MotionXItem(label: 'Settings', icon: Icon(Icons.settings_outlined)),
        ],
      ),
    );
  }
}

Basic Usage #

A complete, production-ready implementation showcasing custom colors, active icons, badges, and smooth notch cutout styling:

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

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

  @override
  State<BasicUsageExample> createState() => _BasicUsageExampleState();
}

class _BasicUsageExampleState extends State<BasicUsageExample> {
  int _selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: MotionXNavigationBar(
        index: _selectedIndex,
        onTabSelected: (index) => setState(() => _selectedIndex = index),
        height: 65.0,
        enableHaptics: true,
        useSafeArea: true,
        animationDuration: const Duration(milliseconds: 350),
        animationCurve: Curves.easeOutCubic,
        indicatorStyle: const MotionXIndicatorStyle(
          shape: MotionXIndicatorShape.floatingCircle,
          size: 56.0,
          color: Color(0xFF6366F1),
          shadows: [
            BoxShadow(
              color: Color(0x406366F1),
              blurRadius: 12.0,
              offset: Offset(0, 4),
            ),
          ],
        ),
        notchStyle: const MotionXNotchStyle(
          enabled: true,
          depth: 0.5,
          cornerRadius: 14.0,
          shape: SmoothNotchShape(cornerRadius: 14.0),
        ),
        items: const [
          MotionXItem(
            label: 'Explore',
            icon: Icon(Icons.explore_outlined),
            activeIcon: Icon(Icons.explore),
          ),
          MotionXItem(
            label: 'Messages',
            icon: Icon(Icons.chat_bubble_outline),
            activeIcon: Icon(Icons.chat_bubble),
            badge: MotionXBadge(
              text: '8',
              badgeSize: 20.0,
              position: MotionXBadgePosition.topRight,
            ),
          ),
          MotionXItem(
            label: 'Updates',
            icon: Icon(Icons.notifications_outlined),
            activeIcon: Icon(Icons.notifications),
            badge: MotionXBadge.dot(
              color: Colors.amber,
              size: 10.0,
            ),
          ),
          MotionXItem(
            label: 'Settings',
            icon: Icon(Icons.settings_outlined),
            activeIcon: Icon(Icons.settings),
          ),
        ],
      ),
    );
  }
}

PageView Synchronization #

Connect MotionXNavigationBar to a PageController using MotionXController. The floating indicator and background notch follow swipe gestures in real time without lag or layout recalculations.

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

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

  @override
  State<PageViewSyncExample> createState() => _PageViewSyncExampleState();
}

class _PageViewSyncExampleState extends State<PageViewSyncExample> {
  late final MotionXController _navController;
  late final PageController _pageController;

  @override
  void initState() {
    super.initState();
    _navController = MotionXController.create(initialIndex: 0);
    _pageController = PageController(initialPage: 0);
    _navController.attachPageController(_pageController);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        controller: _pageController,
        children: const [
          Center(child: Text('Explore Page')),
          Center(child: Text('Messages Page')),
          Center(child: Text('Settings Page')),
        ],
      ),
      bottomNavigationBar: MotionXNavigationBar(
        controller: _navController,
        items: const [
          MotionXItem(label: 'Explore', icon: Icon(Icons.explore)),
          MotionXItem(label: 'Messages', icon: Icon(Icons.chat_bubble)),
          MotionXItem(label: 'Settings', icon: Icon(Icons.settings)),
        ],
      ),
    );
  }
}

Badge Examples #

MotionX includes a flexible badge engine supporting numeric text, dot indicators, custom alignment anchors, pixel nudges, and sizing parameters.

1. Dot Badge #

MotionXBadge.dot(
  color: Colors.red,
  size: 10.0,
  position: MotionXBadgePosition.topRight,
)

2. Number Badge #

MotionXBadge(
  text: '12',
  backgroundColor: const Color(0xFFFF3B30),
  textColor: Colors.white,
  badgeSize: 20.0,
  contentSize: 11.0,
)

3. Text Badge with Outline Border #

MotionXBadge(
  text: 'NEW',
  backgroundColor: const Color(0xFF10B981),
  badgeSize: 22.0,
  contentSize: 10.0,
  padding: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 2.0),
  border: Border.all(color: Colors.white, width: 1.5),
)

4. Custom Position & Offset #

MotionXBadge(
  text: '5',
  position: MotionXBadgePosition(
    alignment: Alignment.topRight,
    offset: Offset(8.0, -2.0),
  ),
  followIndicator: true, // Badge translates with icon lift animation
)

Indicator Styles #

MotionX provides 4 built-in indicator shapes and supports custom vector paths via customPainter:

1. Floating Circle (Default) #

Elevated circular indicator designed to sit above a docked 2D background notch cutout.

MotionXIndicatorStyle(
  shape: MotionXIndicatorShape.floatingCircle,
  size: 56.0,
  color: Color(0xFF6366F1),
)

2. Capsule #

Stadium highlight card centered behind active tab content inside the navigation bar container.

MotionXIndicatorStyle(
  shape: MotionXIndicatorShape.capsule,
  size: 56.0,
  color: Color(0xFF10B981),
)

3. Pill #

Compact floating bar positioned at the top edge of the navigation bar container.

MotionXIndicatorStyle(
  shape: MotionXIndicatorShape.pill,
  size: 56.0,
  color: Color(0xFFEC4899),
)

4. Underline #

Sleek active strip positioned at the bottom edge of the navigation bar container.

MotionXIndicatorStyle(
  shape: MotionXIndicatorShape.underline,
  size: 56.0,
  color: Color(0xFFF59E0B),
)

5. Custom Vector Painter #

Supply a custom CustomPainter to render arbitrary indicator geometry (e.g., diamonds, custom polygons).

MotionXIndicatorStyle(
  shape: MotionXIndicatorShape.custom,
  size: 56.0,
  color: Colors.purple,
  customPainter: MyCustomDiamondPainter(),
)

Notch Styles #

The background notch path is driven by strategy implementations of MotionXNotchShape.

Smooth Bezier Notch (SmoothNotchShape) #

Renders continuous Bezier curves for organic shoulder transitions:

MotionXNotchStyle(
  enabled: true,
  depth: 0.5,
  cornerRadius: 14.0,
  shape: SmoothNotchShape(cornerRadius: 14.0),
)

Classic Circular Arc Notch (ClassicNotchShape) #

Renders classic circular arc geometry:

MotionXNotchStyle(
  enabled: true,
  depth: 0.5,
  shape: ClassicNotchShape(),
)

Customization Reference #

Configuration Area Parameter Description
Bar Container height Overall navigation bar height (defaults to 65.0).
backgroundColor Background bar color (defaults to Theme.of(context).cardColor).
useSafeArea Integrates SafeArea for devices with home indicator bars.
Indicator Style shape floatingCircle, capsule, pill, underline, custom.
size Base indicator size scaling width, height, and thickness proportionally.
color Active indicator fill color.
shadows List of BoxShadow objects for elevation rendering.
Notch Style enabled Enables or disables background notch path geometry.
depth Cradle depth ratio ($0.0 \to 1.0$).
shape SmoothNotchShape or ClassicNotchShape.
Interactions enableHaptics Enables tactile feedback on tab selection.
onTabWillChange Asynchronous interceptor returning bool to approve or cancel tab transitions.

Interactive Example App #

The MotionX repository includes a full-featured Showcase Studio application in example/lib/main.dart.

The showcase app allows developers to interactively tweak indicator shapes, sizes, notch depths, Bezier radii, haptics, RTL directionality, and badge metrics in real time while generating ready-to-use Dart code snippets.

To run the showcase app locally:

cd example
flutter run

Accessibility & Localization #

  • Screen-Reader Semantics: Every tab slot is wrapped in a Semantics widget marked with button: true, selected flags, and configurable semanticLabel values.
  • Material 3 Palette: Fully compatible with Flutter ColorScheme dynamic light and dark themes.
  • RTL Support: Calculates effective layout offsets based on active Directionality, reversing gesture and animation vectors seamlessly for Right-to-Left locales.

Rendering Performance Architecture #

MotionX is designed for high performance:

  • Single Continuous Animation Value: Both floating indicators and background notch cutouts derive 2D coordinates from a single animationOffset value in MotionXController.
  • Canvas-Level Painting: Background paths and notch cutouts are painted at the canvas level inside CustomPainter without instantiating extra layout widgets.
  • No Layout Recalculation: Indicator motion during PageView drags interpolates coordinates mathematically without triggering layout passes.

Roadmap #

Planned features for future releases:

  • ❌ AGSL / SkSL Shaders: Liquid metal and chromatic aberration shader effects for floating indicators.
  • ❌ Vertical Navigation Rail: Adaptive layout adapter for desktop and tablet form factors.
  • ❌ Badge Entry Animations: Scale and bounce entry physics for dynamic badge updates.

Contributing #

Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests on GitHub.

  1. Fork the Repository
  2. Create a Feature Branch (git checkout -b feature/amazing-feature)
  3. Commit Changes (git commit -m 'Add amazing feature')
  4. Push to Branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License #

This project is licensed under the MIT License - see the LICENSE file for details.

0
likes
135
points
30
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A modern, highly customizable Flutter bottom navigation bar with floating indicators, smooth animations, badges, PageView synchronization, and extensible APIs.

Topics

#flutter #navigation #bottom-navigation #animation #ui

License

unknown (license)

Dependencies

flutter

More

Packages that depend on motionx