Slider
什么是 Slider
Slider 是 Flutter 中一个滑块控件,用于在一个连续的范围中选择一个单一的数值(比如音量、亮度、进度条等)。
基本用法
Slider(
value: _currentValue, // 当前值(必须是 double)
min: 0, // 最小值
max: 100, // 最大值
divisions: 10, // 可选:分成多少等份(离散刻度)
label: _currentValue.toString(), // 可选:显示当前值
onChanged: (value) { // 当滑动时回调
setState(() {
_currentValue = value;
});
},
)
常用属性说明
| 属性 | 类型 | 作用 |
|---|---|---|
value |
double |
当前滑块的值 |
min / max |
double |
设置滑动范围(默认 0.0 ~ 1.0) |
divisions |
int? |
设置分段数量,设置后变为离散型 |
label |
String? |
显示在滑块上方的提示文本 |
onChanged |
ValueChanged<double> |
当滑动时回调,必须实现 |
onChangeStart |
ValueChanged<double>? |
开始滑动时回调 |
onChangeEnd |
ValueChanged<double>? |
结束滑动时回调 |
activeColor |
Color? |
已滑动部分轨道的颜色 |
inactiveColor |
Color? |
未滑动部分轨道的颜色 |
thumbColor |
Color? |
滑块圆点的颜色 |
入门案例
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: MySliderDemo()));
}
class MySliderDemo extends StatefulWidget {
const MySliderDemo({super.key});
@override
State<MySliderDemo> createState() => _MySliderDemoState();
}
class _MySliderDemoState extends State<MySliderDemo> {
double _currentValue = 50;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Slider 示例')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Slider(
value: _currentValue,
min: 0,
max: 100,
divisions: 10,
label: _currentValue.toStringAsFixed(0),
activeColor: Colors.blue,
inactiveColor: Colors.grey,
onChanged: (value) {
debugPrint("执行时调用:$value");
setState(() {
_currentValue = value;
});
},
onChangeStart: (value) {
print("开始滑动:$value");
},
onChangeEnd: (value) {
print("结束滑动:$value");
},
),
const SizedBox(height: 20),
Text('当前值: ${_currentValue.toStringAsFixed(0)}'),
],
),
),
);
}
}
// 日志:
Restarted application in 3,536ms.
I/flutter ( 4845): 开始滑动:50.0
I/flutter ( 4845): 执行时调用:60.0
I/flutter ( 4845): 执行时调用:70.0
I/flutter ( 4845): 执行时调用:80.0
I/flutter ( 4845): 结束滑动:80.0
another_xlider
是什么
another_xlider 是 Dart / Flutter 的一个功能更强大的滑块(Slider)组件库,用来替代原生的 Slider。它支持 单滑块(Single Slider) 和 范围滑块(Range Slider),提供了丰富的 自定义样式 和 交互事件,非常适合在需要精美 UI 或复杂交互的场景使用,比如价格筛选、音量控制、进度选择等。
FlutterSlider 是 another_xlider 包中的主组件,用来创建:
- 单滑块(Single Slider)
- 双滑块(Range Slider)
- 垂直滑块
- 带自定义刻度、标签、气泡提示的滑块
相比原生 Slider 控件,它可以:
- 自定义滑块形状(thumb)
- 自定义轨道样式(track/bar)
- 同时显示两个滑块(range)
- 显示当前数值的提示(tooltip)
- 限制步长、范围等
常用属性
| 参数名 | 类型 | 说明 |
|---|---|---|
values |
List<double> |
当前滑块位置(单滑块只传一个) |
min / max |
double |
范围最小值 / 最大值 |
rangeSlider |
bool |
是否启用范围滑块(两个滑块头) |
onDragging |
回调函数 | 拖动过程中实时回调,提供当前值 |
onDragCompleted |
回调函数 | 拖动完成时触发 |
handler / rightHandler |
FlutterSliderHandler |
自定义左右滑块样式 |
trackBar |
FlutterSliderTrackBar |
自定义轨道样式 |
tooltip |
FlutterSliderTooltip |
显示当前值的提示气泡 |
step |
FlutterSliderStep |
设定步进间隔 |
步长FlutterSliderStep
FlutterSliderStep 是 another_xlider 包中 FlutterSlider 的一个配置类,用来设置滑块移动时的步进规则。简单来说,就是限制滑块值的间隔:滑块每次只能停在指定的间隔点上,而不能自由滑动到任意值。
const FlutterSliderStep({
this.step = 1,
this.isPercentRange = true,
this.rangeList,
});
FlutterSliderStep 有以下几个常见属性:
| 属性名 | 类型 | 说明 |
|---|---|---|
step |
double |
步长:每次滑动的最小间隔。例如 step: 5 时,滑块只能在 0、5、10、15…这些位置上停下来 |
rangeList |
List<FlutterSliderRangeStep> |
设置区间化的步长,可以在不同区间内使用不同的 step(进阶功能) |
isPercentRange |
bool |
如果为 true,rangeList 中的范围会按百分比计算(0-100%)而不是实际值 |
step: FlutterSliderStep(
rangeList: [
FlutterSliderRangeStep(from: 0, to: 50, step: 5),
FlutterSliderRangeStep(from: 50, to: 100, step: 10),
],
)
意思是:
- 0~50 之间:每次走 5
- 50~100 之间:每次走 10
这样可以实现非线性刻度的滑块。
FlutterSliderHandler:滑块样式
FlutterSliderHandler 用于自定义 FlutterSlider 的**滑块按钮(thumb/handle)**的外观和行为。
如果你想修改滑块按钮的大小、形状、颜色、阴影,或者在按钮里显示文字/图标,就需要配置这个。
| 属性名 | 类型 | 说明 |
|---|---|---|
child |
Widget? |
自定义按钮的内容,比如 Icon、Text、Container 等 |
width |
double? |
按钮宽度 |
height |
double? |
按钮高度 |
decoration |
BoxDecoration? |
按钮外观装饰(背景颜色、圆角、边框、阴影等) |
elevation |
double? |
按钮的阴影高度 |
foregroundDecoration |
Decoration? |
叠加在 child 前面的装饰(不常用) |
rotationAngle |
double? |
旋转角度(单位:弧度) |
disabled |
bool |
是否禁用此按钮(无法拖动) |
alwaysVisible |
bool |
是否始终显示按钮(即使不选中时) |
opacity |
double? |
不透明度(0~1) |
scale |
double? |
缩放比例(默认 1) |
FlutterSliderTrackBar:滑轨样式
在 Flutter 的 another_xlider 包中,FlutterSliderTrackBar 用于自定义滑轨(track bar)的样式,也就是滑块下面那条水平轨道,包括:
- 整条轨道的背景样式
- 已滑过部分(active track)的样式
- 未滑过部分(inactive track)的样式
| 属性名 | 类型 | 说明 |
|---|---|---|
activeTrackBar |
BoxDecoration |
已滑过的轨道部分样式(左侧) |
inactiveTrackBar |
BoxDecoration |
未滑过的轨道部分样式(右侧) |
activeTrackBarHeight |
double? |
已滑过部分轨道的高度 |
inactiveTrackBarHeight |
double? |
未滑过部分轨道的高度 |
FlutterSliderTooltip:提示气泡
FlutterSliderTooltip 是用于**配置滑块(Slider)提示气泡(Tooltip)**的类,它决定当用户拖动滑块时,显示在滑块上方的小提示框的外观与行为。
当用户拖动滑块(Slider)时,通常会显示当前值,FlutterSliderTooltip 就是专门用来**控制这些提示框(tooltip)**的显示效果、样式、位置等的。
| 属性名 | 类型 | 作用 |
|---|---|---|
enabled |
bool |
是否启用 tooltip(默认 true)。 |
alwaysShowTooltip |
bool |
是否总是显示 tooltip(而不是仅在拖动时显示)。 |
disableAnimation |
bool |
是否禁用 tooltip 的出现/消失动画。 |
format |
String Function(String value) |
自定义显示的文字格式,比如可以加单位等。 |
custom |
Widget Function(String value) |
完全自定义 tooltip 的内容(返回一个 Widget)。 |
positionOffset |
double |
控制 tooltip 相对于滑块的垂直位置偏移。 |
direction |
FlutterSliderTooltipDirection |
控制 tooltip 显示在滑块上方还是下方(top / bottom)。 |
textStyle |
TextStyle |
设置 tooltip 文字的样式。 |
boxStyle |
FlutterSliderTooltipBox |
设置 tooltip 容器(背景、边框、圆角等)的样式。 |
onDragging
触发时机:拖动过程中,每移动一点都会触发。
触发频率:非常高(连续触发)。
常见用途:
- 实时显示滑块当前数值(比如更新 UI 文本)。
- 实时控制其它部件(例如音量大小、实时刷新图表等)。
onDragging: (handlerIndex, lowerValue, upperValue) {
print("正在拖动:$lowerValue ~ $upperValue");
}
| 参数名 | 类型 | 含义 |
|---|---|---|
handlerIndex |
int |
表示当前正在拖动的是哪一个滑块手柄(handler)— 如果是单滑块,一般为 0— 如果是双滑块,左滑块为 0,右滑块为 1 |
lowerValue |
dynamic(通常是 double) |
当前左侧滑块的数值(如果是单滑块,这就是当前滑块值) |
upperValue |
dynamic(通常是 double) |
当前右侧滑块的数值(如果是单滑块,这个值等于 lowerValue) |
onDragCompleted
触发时机:松开手指(结束拖动)时触发一次。
触发频率:只在一次拖动结束时触发一次。
常见用途:
- 保存最终结果(比如发送网络请求、更新数据库)。
- 避免频繁刷新(拖动中不操作,松开后再一次性处理)。
// 参数的含义和 onDragging 的一样
onDragCompleted: (handlerIndex, lowerValue, upperValue) {
print("拖动完成:$lowerValue ~ $upperValue");
}
案例
import 'package:another_xlider/another_xlider.dart';
import 'package:another_xlider/models/handler.dart';
import 'package:another_xlider/models/slider_step.dart';
import 'package:another_xlider/models/tooltip/tooltip.dart';
import 'package:another_xlider/models/tooltip/tooltip_box.dart';
import 'package:another_xlider/models/trackbar.dart';
import 'package:flutter/material.dart';
// import 'package:flutter_xlider/flutter_xlider.dart'; // another_xlider
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.blue),
home: const PriceFilterPage(),
);
}
}
class PriceFilterPage extends StatefulWidget {
const PriceFilterPage({super.key});
@override
State<PriceFilterPage> createState() => _PriceFilterPageState();
}
class _PriceFilterPageState extends State<PriceFilterPage> {
List<double> _values = [100, 800]; // 初始价格范围
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('价格区间筛选器')),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'选择价格区间',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 40),
// 价格区间滑块
FlutterSlider(
values: _values, // 当前选中范围
max: 1000, // 最大值
min: 0, // 最小值
rangeSlider: true, // 开启范围选择,开启范围表示会有两个滑块
step: const FlutterSliderStep(step: 50), // 步长 50
// 自定义左滑块样式
handler: FlutterSliderHandler(
decoration: const BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
child: const Icon(Icons.circle, color: Colors.white, size: 20),
),
// 自定义右滑块样式
rightHandler: FlutterSliderHandler(
decoration: const BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
child: const Icon(Icons.circle, color: Colors.white, size: 20),
),
// 自定义轨道样式
trackBar: FlutterSliderTrackBar(
activeTrackBar: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(4),
),
inactiveTrackBar: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(4),
),
),
// 显示当前值的气泡
tooltip: FlutterSliderTooltip(
alwaysShowTooltip: true,
textStyle: const TextStyle(color: Colors.white),
boxStyle: FlutterSliderTooltipBox(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.7),
),
),
// 格式化显示内容,前面加上 $
format: (value) => '\$${double.parse(value)}',
),
// 拖动时更新值
onDragging: (handlerIndex, lowerValue, upperValue) {
setState(() => _values = [lowerValue, upperValue]);
},
),
const SizedBox(height: 40),
Text(
'当前选择:\$${_values[0].toInt()} - \$${_values[1].toInt()}',
style: const TextStyle(fontSize: 16),
),
],
),
),
);
}
}