滑动控件:another_xlider和Slider

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 或复杂交互的场景使用,比如价格筛选、音量控制、进度选择等。

FlutterSlideranother_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

FlutterSliderStepanother_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 如果为 truerangeList 中的范围会按百分比计算(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? 自定义按钮的内容,比如 IconTextContainer
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),
            ),
          ],
        ),
      ),
    );
  }
}

×

喜欢就点赞,疼爱就打赏