我的问题非常简单:有什么方法可以在不活动的范围滑块拇指周围设置模糊的阴影?问题恰恰出在范围滑块的非活动拇指上,我需要的不是像这样的高度或类似的东西,而是拇指周围模糊的阴影。 我只能为滑块的活动拇指创建所需的阴影,但不能为非活动拇指创建所需的阴影,即用户尚未触摸的拇指
代码:
class PriceRangeSlider extends StatelessWidget {
const PriceRangeSlider({
Key? key,
required this.currentRangeValues,
required this.onChanged,
required this.minPrice,
required this.maxPrice,
}) : super(key: key);
final RangeValues currentRangeValues;
final ValueChanged<RangeValues> onChanged;
final double minPrice;
final double maxPrice;
@override
Widget build(BuildContext context) {
final ThemeColors colors = context.colors;
final SliderThemeData sliderData = SliderTheme.of(context).copyWith(
activeTrackColor: colors.darkText,
inactiveTrackColor: colors.lightGrey,
trackHeight: Di.p4,
thumbColor: colors.contrastWhite,
thumbShape: CustomThumbShape(),
overlayShape: RoundSliderOverlayShape(overlayRadius: 0),
);
return Padding(
padding: const Pad(top: Di.p20),
child: SliderTheme(
data: sliderData,
child: RangeSlider(
values: currentRangeValues,
min: minPrice,
max: maxPrice,
onChanged: onChanged,
),
),
);
}
}
class CustomThumbShape extends SliderComponentShape {
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return Size(24.0, 24.0);
}
@override
void paint(
PaintingContext context,
Offset offset,
{required Animation<double> activationAnimation,
required Animation<double> enableAnimation,
required bool isDiscrete,
required TextPainter labelPainter,
required RenderBox parentBox,
required Size sizeWithOverflow,
required SliderThemeData sliderTheme,
required TextDirection textDirection,
required double textScaleFactor,
required double value}) {
final Canvas canvas = context.canvas;
final double outerRadius = 16.0;
final double innerRadius = 12.0;
final Paint shadowPaint = Paint()
..color = Colors.black.withOpacity(0.4)
..style = PaintingStyle.fill;
final Paint outerPaint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 2.0;
final Paint innerPaint = Paint()
..color = Colors.black
..style = PaintingStyle.fill;
canvas.drawCircle(offset, outerRadius + 6, shadowPaint);
canvas.drawCircle(offset, outerRadius, outerPaint);
canvas.drawCircle(offset, innerRadius, innerPaint);
final Offset inactiveOffset = Offset(offset.dx + 20, offset.dy);
final Paint inactiveShadowPaint = Paint()
..color = Colors.red.withOpacity(0.6)
..style = PaintingStyle.fill;
canvas.drawCircle(inactiveOffset, outerRadius + 45, inactiveShadowPaint);
canvas.drawCircle(inactiveOffset, outerRadius, outerPaint);
canvas.drawCircle(inactiveOffset, innerRadius, innerPaint);
}
}
您首先必须了解的一件事是,两个拇指都是使用相同的形状类绘制的。不过,好的一点是我们应该能够检测到我们当前正在绘制哪个拇指
这是一个例子
class CustomThumbShape extends SliderComponentShape {
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
// Include space for shadow
return const Size(32.0, 32.0);
}
@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,
}) {
final canvas = context.canvas;
// Shadow paint with blur effect
final shadowPaint = Paint()
..color = Colors.black.withOpacity(0.3)
..maskFilter = const MaskFilter.blur(BlurStyle.normal, 8);
// Main thumb paint
final thumbPaint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
// Draw shadow first
canvas.drawCircle(center, 12, shadowPaint);
// Draw thumb on top
canvas.drawCircle(center, 12, thumbPaint);
}
}
关键是在阴影颜料中使用
MaskFilter.blur
。这会创建适用于两个拇指的适当模糊阴影效果。像这样将其应用到您的 RangeSlider 中:
SliderTheme(
data: SliderThemeData(
thumbShape: CustomThumbShape(),
...
),
child: RangeSlider(
...
),
)
希望这有帮助