lib/ui/aliplayer_custom_slider_widget.dart (107 lines of code) (raw):
// Copyright © 2025 Alibaba Cloud. All rights reserved.
//
// Author: keria
// Date: 2025/2/12
// Brief: 自定义滑块控件
import 'package:flutter/material.dart';
/// 自定义滑块控件,用于显示一个带有文本和图标的滑块组件。
class AliPlayerCustomSliderWidget extends StatefulWidget {
/// 显示的文本
final String text;
/// 起始图标
final IconData startIcon;
/// 结束图标
final IconData endIcon;
/// 初始值
final double initialValue;
/// 滑块值变化时的回调(仅在可交互模式下有效)
final ValueChanged<double>? onChanged;
/// 是否可交互(可拖动)
final bool isInteractive;
const AliPlayerCustomSliderWidget({
super.key,
required this.text,
required this.startIcon,
required this.endIcon,
required this.initialValue,
this.onChanged,
this.isInteractive = true, // 默认为可交互
});
@override
State<AliPlayerCustomSliderWidget> createState() =>
_AliPlayerCustomSliderWidgetState();
}
class _AliPlayerCustomSliderWidgetState
extends State<AliPlayerCustomSliderWidget> {
// 当前滑块的值
late double _sliderValue;
@override
void initState() {
super.initState();
_sliderValue = _roundToTwoDecimals(widget.initialValue);
}
/// 更新滑块值并触发回调
void _onSliderChanged(double value) {
if (!widget.isInteractive) return; // 如果不可交互,则直接返回
// 将滑块值保留两位小数
final roundedValue = _roundToTwoDecimals(value);
setState(() {
_sliderValue = roundedValue;
});
widget.onChanged?.call(roundedValue); // 触发回调
}
/// 将数值保留两位小数
static double _roundToTwoDecimals(double value) {
return (value * 100).round() / 100;
}
/// 构建自定义滑块控件
///
/// Builds the custom slider widget.
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
widget.text,
style: const TextStyle(
fontSize: 12,
color: Colors.black,
),
),
const SizedBox(width: 4),
Icon(
widget.startIcon,
size: 16,
),
const SizedBox(width: 4),
Expanded(
child: SliderTheme(
data: _getSliderThemeData(),
child: Slider(
value: _sliderValue,
onChanged: widget.isInteractive ? _onSliderChanged : null,
// 根据状态决定是否允许拖动
min: 0.0,
max: 1.0,
),
),
),
const SizedBox(width: 4),
Icon(
widget.endIcon,
size: 16,
),
],
);
}
/// 获取 SliderTheme 数据
///
/// Returns the SliderThemeData configuration.
SliderThemeData _getSliderThemeData() {
return SliderTheme.of(context).copyWith(
trackHeight: 2.0,
thumbShape: widget.isInteractive
? const RoundSliderThumbShape(
enabledThumbRadius: 4.0,
elevation: 2.0,
)
: const RoundSliderThumbShape(
enabledThumbRadius: 0.0,
elevation: 0.0,
),
activeTrackColor: Colors.grey,
inactiveTrackColor: Colors.grey[300],
thumbColor: widget.isInteractive ? Colors.grey : Colors.transparent,
overlayColor: widget.isInteractive
? Colors.grey[400]?.withAlpha(32)
: Colors.transparent,
);
}
/// 状态更新回调
///
/// Called when the state of the widget is updated.
@override
void didUpdateWidget(covariant AliPlayerCustomSliderWidget oldWidget) {
super.didUpdateWidget(oldWidget);
// 如果外部传递的 initialValue 发生变化,则同步更新内部状态
if (widget.initialValue != oldWidget.initialValue) {
setState(() {
_sliderValue = _roundToTwoDecimals(widget.initialValue);
});
}
}
}