motion_segment 0.1.3
motion_segment: ^0.1.3 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