motion_segment 0.1.2 copy "motion_segment: ^0.1.2" to clipboard
motion_segment: ^0.1.2 copied to clipboard

A highly customizable animated segmented button for Flutter with smooth sliding indicator animations.

motion_segment #

A highly customizable animated segmented button for Flutter with a smooth sliding selection indicator.

Features #

  • Smooth sliding indicator animation between segments
  • Four indicator animation styles: none, squish, bounce, stretch
  • Horizontal and vertical layouts
  • Per-state icon and label customization via WidgetStateProperty
  • Customizable colors, border radius, margins, and spacing
  • Custom animation duration and curve
  • Light and dark theme support
  • Supports Android, iOS, Web, Windows, macOS, and Linux

Installation #

Add motion_segment to your pubspec.yaml:

dependencies:
  motion_segment: ^0.1.2

Then run:

flutter pub get

Basic Usage #

import 'package:motion_segment/motion_segment.dart';

int _selectedIndex = 0;

SizedBox(
  height: 52,
  child: MotionSegment(
    selectedIndex: _selectedIndex,
    onChanged: (value) {
      setState(() => _selectedIndex = value);
    },
    backgroundColor: Colors.grey.shade200,
    indicatorAnimation: SegmentIndicatorAnimation.squish,
    selections: [
      MotionSegmentSelections(
        selectedColor: Colors.blue,
        label: WidgetStateProperty.resolveWith((states) => Text(
          'Day',
          style: TextStyle(
            color: states.contains(WidgetState.selected)
                ? Colors.white
                : Colors.black54,
          ),
        )),
      ),
      MotionSegmentSelections(
        selectedColor: Colors.blue,
        label: WidgetStateProperty.resolveWith((states) => Text(
          'Week',
          style: TextStyle(
            color: states.contains(WidgetState.selected)
                ? Colors.white
                : Colors.black54,
          ),
        )),
      ),
      MotionSegmentSelections(
        selectedColor: Colors.blue,
        label: WidgetStateProperty.resolveWith((states) => Text(
          'Month',
          style: TextStyle(
            color: states.contains(WidgetState.selected)
                ? Colors.white
                : Colors.black54,
          ),
        )),
      ),
    ],
  ),
)

Vertical Layout #

SizedBox(
  height: 180,
  width: 64,
  child: MotionSegment(
    selectionDirection: SelectionDirection.vertical,
    selectedIndex: _selectedIndex,
    onChanged: (value) => setState(() => _selectedIndex = value),
    indicatorAnimation: SegmentIndicatorAnimation.bounce,
    selections: [
      MotionSegmentSelections(
        selectedColor: Colors.blue,
        icon: WidgetStateProperty.resolveWith((states) => Icon(
          Icons.home,
          color: states.contains(WidgetState.selected)
              ? Colors.white
              : Colors.black54,
        )),
      ),
      MotionSegmentSelections(
        selectedColor: Colors.blue,
        icon: WidgetStateProperty.resolveWith((states) => Icon(
          Icons.search,
          color: states.contains(WidgetState.selected)
              ? Colors.white
              : Colors.black54,
        )),
      ),
      MotionSegmentSelections(
        selectedColor: Colors.blue,
        icon: WidgetStateProperty.resolveWith((states) => Icon(
          Icons.person,
          color: states.contains(WidgetState.selected)
              ? Colors.white
              : Colors.black54,
        )),
      ),
    ],
  ),
)

MotionSegment Parameters #

Parameter Type Default Description
selections List<MotionSegmentSelections> required The segments to display
onChanged ValueChanged<int>? null Called when a segment is tapped
selectedIndex int? 0 The initially selected segment index
selectionDirection SelectionDirection? horizontal Axis of layout
indicatorAnimation SegmentIndicatorAnimation? null Indicator animation style
backgroundColor Color? theme canvasColor Background color
borderRadius BorderRadiusGeometry? circular(8) Border radius
margins double? 4.0 Padding around segments
selectionsSpacing double? 0 Spacing between segments
animationDuration Duration? 250ms Animation duration
animationCurve Curve? easeInOutCubic Animation curve

MotionSegmentSelections Parameters #

Parameter Type Description
selectedColor Color? Indicator color when this segment is selected
icon WidgetStateProperty<Widget?>? Icon with per-state customization
label WidgetStateProperty<Widget?>? Label with per-state customization
hoverColor Color? Hover overlay color
mouseCursor MouseCursor? Cursor on hover, defaults to click

Indicator Animation Styles #

Style Description
none Slides without shape change
squish Squishes horizontally mid-slide
bounce Overshoots and bounces on arrival
stretch Stretches across segments during slide

Layout Constraints #

MotionSegment expands to fill its parent's constraints. When used inside a Row, wrap with Expanded or give it an explicit width. When using vertical layout inside a Column, wrap with Expanded or give it an explicit height.

// Inside a Row
Row(
  children: [
    Expanded(child: MotionSegment(...)),
  ],
)

// Explicit size
SizedBox(
  height: 52,
  child: MotionSegment(...),
)

License #

MIT

0
likes
160
points
304
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A highly customizable animated segmented button for Flutter with smooth sliding indicator animations.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on motion_segment