FlutterFlow provides built-in Slider and LinearPercentIndicator widgets for input and display. Bind a Slider's value to a Page State double variable via the On Changed action to create interactive controls. Use LinearPercentIndicator for horizontal progress bars with animated fill, and CircularPercentIndicator for radial progress rings. For range selection (e.g., price filter with min and max), build a Custom Widget using Flutter's RangeSlider widget since it is not available in the visual builder.
Building Sliders and Progress Bars in FlutterFlow
Sliders and progress bars are essential for settings (volume, brightness), filters (price range), and feedback (completion progress, ratings). This tutorial covers all four: standard Slider, linear progress, circular progress, and range slider.
Prerequisites
- A FlutterFlow project open in the builder
- Understanding of Page State variables and data binding
- FlutterFlow Pro plan for the RangeSlider Custom Widget
Step-by-step guide
Add a Slider widget and bind its value to Page State
Add a Slider widget and bind its value to Page State
Add a Page State variable called sliderValue (double, default 50). Drag a Slider widget from the Widget Palette. In Properties Panel, set min to 0, max to 100, and divisions to 20 (creates steps of 5). Set activeColor to Theme Primary and inactiveColor to grey200. Bind the value to the sliderValue Page State variable. On the Slider's On Changed action, add Update Page State → set sliderValue to the new value. Add a Text widget nearby bound to sliderValue to display the current number.
Expected result: Dragging the slider updates the displayed value in real-time between 0 and 100.
Add a LinearPercentIndicator for horizontal progress display
Add a LinearPercentIndicator for horizontal progress display
Drag a LinearPercentIndicator from the Widget Palette (or search for it). Set lineHeight to 12, progressColor to Theme Primary, backgroundColor to grey200, barRadius to 6 (rounded ends). Bind the percent property to a calculated value between 0.0 and 1.0 — for example, completedTasks / totalTasks. Enable animation and set animationDuration to 800 milliseconds for a smooth fill effect when the percentage changes.
Expected result: A rounded progress bar fills with animated color based on the bound percentage value.
Add a CircularPercentIndicator for radial progress display
Add a CircularPercentIndicator for radial progress display
Drag a CircularPercentIndicator widget. Set radius to 60, lineWidth to 10, progressColor to Theme Primary, backgroundColor to grey200. Bind percent to your progress value (0.0-1.0). Add a center Text widget showing the percentage as text (e.g., '75%'). Enable animation with duration 1000ms. This creates a donut-style progress ring commonly used for completion scores, battery level, or skill proficiency.
Expected result: A circular progress ring displays the percentage with an animated fill and center text label.
Build a RangeSlider Custom Widget for min/max selection
Build a RangeSlider Custom Widget for min/max selection
Create a Custom Widget called PriceRangeSlider with parameters: min (double), max (double), onChanged (Action with two doubles). In the Dart code, use Flutter's RangeSlider widget with RangeValues tracked in Component State. Style with activeColor from Theme and inactive from grey. On changed, update Component State and call the onChanged callback with the new min and max values. Display the current range values as Text labels above the slider.
1class PriceRangeSlider extends StatefulWidget {2 const PriceRangeSlider({3 super.key, this.width, this.height,4 required this.min, required this.max,5 this.onRangeChanged,6 });7 final double? width;8 final double? height;9 final double min;10 final double max;11 final Future Function(double start, double end)? onRangeChanged;1213 @override14 State<PriceRangeSlider> createState() => _PriceRangeSliderState();15}1617class _PriceRangeSliderState extends State<PriceRangeSlider> {18 late RangeValues _values;1920 @override21 void initState() {22 super.initState();23 _values = RangeValues(widget.min, widget.max);24 }2526 @override27 Widget build(BuildContext context) {28 return SizedBox(29 width: widget.width ?? double.infinity,30 child: Column(31 mainAxisSize: MainAxisSize.min,32 children: [33 Row(34 mainAxisAlignment: MainAxisAlignment.spaceBetween,35 children: [36 Text('\$${_values.start.round()}'),37 Text('\$${_values.end.round()}'),38 ],39 ),40 RangeSlider(41 values: _values,42 min: widget.min,43 max: widget.max,44 divisions: ((widget.max - widget.min) / 10).round(),45 onChanged: (values) {46 setState(() => _values = values);47 widget.onRangeChanged?.call(values.start, values.end);48 },49 ),50 ],51 ),52 );53 }54}Expected result: A two-thumb slider for selecting a min/max range with displayed labels.
Combine sliders and progress bars in a settings or filter page
Combine sliders and progress bars in a settings or filter page
Build a complete settings page combining these widgets. Use Slider for volume or notification frequency settings. Use LinearPercentIndicator in a profile completion card showing how much of their profile the user has filled out. Use CircularPercentIndicator on a dashboard for goal progress. Use PriceRangeSlider in a product filter bottom sheet for price range selection.
Expected result: A cohesive page or set of features using sliders for input and progress indicators for display.
Complete working example
1import 'package:flutter/material.dart';23class PriceRangeSlider extends StatefulWidget {4 const PriceRangeSlider({5 super.key,6 this.width,7 this.height,8 required this.min,9 required this.max,10 this.onRangeChanged,11 });1213 final double? width;14 final double? height;15 final double min;16 final double max;17 final Future Function(double start, double end)? onRangeChanged;1819 @override20 State<PriceRangeSlider> createState() => _PriceRangeSliderState();21}2223class _PriceRangeSliderState extends State<PriceRangeSlider> {24 late RangeValues _values;2526 @override27 void initState() {28 super.initState();29 _values = RangeValues(widget.min, widget.max);30 }3132 @override33 Widget build(BuildContext context) {34 return SizedBox(35 width: widget.width ?? double.infinity,36 child: Column(37 mainAxisSize: MainAxisSize.min,38 children: [39 Padding(40 padding: const EdgeInsets.symmetric(horizontal: 16),41 child: Row(42 mainAxisAlignment: MainAxisAlignment.spaceBetween,43 children: [44 Text(45 '\$${_values.start.round()}',46 style: Theme.of(context).textTheme.bodyMedium,47 ),48 Text(49 '\$${_values.end.round()}',50 style: Theme.of(context).textTheme.bodyMedium,51 ),52 ],53 ),54 ),55 SliderTheme(56 data: SliderThemeData(57 activeTrackColor: Theme.of(context).primaryColor,58 inactiveTrackColor: Colors.grey[200],59 thumbColor: Theme.of(context).primaryColor,60 overlayColor:61 Theme.of(context).primaryColor.withOpacity(0.2),62 trackHeight: 4,63 ),64 child: RangeSlider(65 values: _values,66 min: widget.min,67 max: widget.max,68 divisions: ((widget.max - widget.min) / 10).round(),69 onChanged: (RangeValues values) {70 setState(() => _values = values);71 widget.onRangeChanged?.call(values.start, values.end);72 },73 ),74 ),75 ],76 ),77 );78 }79}Common mistakes when creating Custom Sliders and Progress Bars in FlutterFlow
Why it's a problem: Setting Slider max to 1 when displaying values as percentages 0-100
How to avoid: Either set max to 100 and display the value directly, or set max to 1.0 and multiply the display value by 100 with a Custom Function.
Why it's a problem: Not setting divisions on the Slider for stepped values
How to avoid: Set divisions to create discrete steps. For a 0-100 slider with steps of 5, set divisions to 20.
Why it's a problem: Passing a value outside 0.0-1.0 to LinearPercentIndicator
How to avoid: Divide your raw value by the total to get a 0.0-1.0 fraction: completedTasks / totalTasks.
Best practices
- Bind Slider values to Page State with On Changed for real-time updates
- Use divisions on Sliders for predictable stepped values users can target
- Set LinearPercentIndicator animation to true for smooth transitions when progress changes
- Show the current value as a Text label near the Slider for clarity
- Use CircularPercentIndicator for compact spaces like dashboard cards
- Build RangeSlider as a Custom Widget since it is not available in the visual builder
- Keep progress bar colors consistent with your Theme for visual cohesion
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to build sliders and progress bars in FlutterFlow. Show me how to configure a Slider bound to Page State, a LinearPercentIndicator with animation, a CircularPercentIndicator with center text, and a Custom Widget RangeSlider for price range selection.
Add a Slider to my page. Set min to 0, max to 100, divisions to 10. Set the active color to my primary theme color. Add a text widget next to it showing the current value.
Frequently asked questions
Can I customize the slider thumb shape?
Not in the visual builder. Use a Custom Widget with SliderTheme to customize thumb shape, size, and color using SliderComponentShape.
Does LinearPercentIndicator support gradient colors?
Yes. Set linearGradient instead of progressColor to apply a gradient fill. Pass two or more Colors for the gradient stops.
Can I make the progress bar animate on page load?
Yes. Set the percent to 0 initially, then update it to the target value in an On Page Load action. With animation enabled, it fills from 0 to the target.
How do I create a vertical progress bar?
LinearPercentIndicator does not support vertical orientation. Rotate it 90 degrees with a Transform.rotate Custom Widget, or use a Container with a dynamic height.
Can I use a Slider for star ratings?
A Slider works but is not ideal for star ratings. Use a Custom Widget with a Row of tappable star icons (5 Icons) for a traditional star rating experience.
Can RapidDev help with custom progress visualizations?
Yes. RapidDev can build gradient progress rings, animated step indicators, multi-segment bars, and custom slider designs.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation