Slider
是 Flutter 中用于选择一个范围内值的控件,通常用于调节音量、亮度等场景。它允许用户通过拖动滑块来选择数值。
一、Slider的基本属性
主要属性
-
value
:当前滑块的值。 -
onChanged
:当滑块的值发生变化时调用的回调函数。 -
min
:滑块的最小值,默认为 0.0。 -
max
:滑块的最大值,默认为 1.0。 -
divisions
:将滑块分成若干等份,设置后滑块会吸附到这些点上。 -
label
:滑块上显示的标签,通常与divisions
一起使用。 -
activeColor
:滑块活动部分的颜色。 -
inactiveColor
:滑块非活动部分的颜色。
Slider的其他属性也可以在Flutter文档中查看。
二、自定义Slider滑块样式
通过 SliderTheme
来自定义 Slider
的外观。示例如下:
SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor: Colors.red,
inactiveTrackColor: Colors.grey,
thumbColor: Colors.blue,
overlayColor: Colors.blue.withOpacity(0.2),
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 12.0),
overlayShape: RoundSliderOverlayShape(overlayRadius: 20.0),
),
child: Slider(
value: _currentValue,
min: 0.0,
max: 100.0,
onChanged: (double value) {
setState(() {
_currentValue = value;
});
},
),
);
三、使用Image自定义ThumeShape
如果想要根复杂的滑块样式,可以自定义thumbShape属性,使用Image达到效果。
自定义ImageSliderThumb 继承SliderComponentShape,重写paint函数,绘制自定义滑块样式。
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
class ImageSliderThumb extends SliderComponentShape {
final Size size;
final ui.Image? image;
const ImageSliderThumb({required this.image, Size? size})
: size = size ?? const Size(20, 20);
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return size;
}
@override
void paint(PaintingContext context, Offset center,
{required Animation<double> activationAnimation,
required Animation<double> enableAnimation,
required bool isDiscrete,
required TextPainter labelPainter,
required RenderBox parentBox,
required SliderThemeData sliderTheme,
required TextDirection textDirection,
required double value,
required double textScaleFactor,
required Size sizeWithOverflow}) {
//图片中心点
double dx = size.width / 2;
double dy = size.height / 2;
if (image != null) {
final Rect sourceRect =
Rect.fromLTWH(0, 0, image!.width.toDouble(), image!.width.toDouble());
//center会随着滑块的移动而改变,所以这里需要根据center计算图片绘制的位置
double left = center.dx - dx;
double top = center.dy - dy;
double right = center.dx + dx;
double bottom = center.dy + dy;
Rect destinationRect = Rect.fromLTRB(left, top, right, bottom);
final Canvas canvas = context.canvas;
final Paint paint = Paint();
paint.isAntiAlias = true;
//绘制滑块
canvas.drawImageRect(image!, sourceRect, destinationRect, paint);
}
}
}
传入的image参数是ui.Image,不能直接使用Image(),方法如下:
ui.Image? imageInfo;
Future<void> loadImage() async {
final ByteData data =
await rootBundle.load('assets/images.png');//图片路径
final Codec codec =
await ui.instantiateImageCodec(data.buffer.asUint8List());
final FrameInfo frameInfo = await codec.getNextFrame();
setState(() {
imageInfo = frameInfo.image;
});
}
调用代码参考:
SliderTheme(
data: SliderTheme.of(context).copyWith(
trackHeight: 9, // 设置轨道高度
inactiveTrackColor: Colors.black.withOpacity(0.1),
activeTrackColor: Colors.white,
// 方法调用
thumbShape: ImageSliderThumb(
image: imageInfo, size: const Size(22, 22))
),
child: Slider(
value: 60.0,
onChanged: (double value) {},
onChangeEnd: (double value) {},
min: 0.0,
max: 100,
),
),