如何在Flutter滑块小部件中设置自定义的刻度标记形状

5

我正在尝试在我的Flutter项目中制作自定义刻度标记形状。 根据文档,我了解到可以使用SliderTickMarkShape来控制刻度标记的形状。 但是,它只提供了一个选项SliderTickMarkShape.noTickMark,它会删除刻度标记形状,但我想把它做成像棍子一样的形状。 那么我该如何在Flutter中设置自定义刻度标记形状呢?谢谢。


1
文档中写道:“Slider刻度标记形状的基类。如果您想要自定义Slider刻度标记形状,请创建此类的子类。可以通过为SliderThemeData.tickMarkShape指定noTickMark来跳过刻度标记绘制。”- 因此,如果您想要自己的自定义刻度标记,则必须“创建此类的子类”。 - pskink
当然,不客气。 - pskink
1个回答

4
为了定制如下图所示的tick(刻度线): enter image description here 您需要扩展SliderTickMarkShape。在这种情况下,我称之为LineSliderTickMarkShape。以下是源代码,但基本上是RoundSliderTickMarkShape的副本,它只是更改了context.canvas.drawLine的绘制方式以定制标记的形状。RoundSliderTickMarkShape是默认的刻度线形状。
class LineSliderTickMarkShape extends SliderTickMarkShape {
  const LineSliderTickMarkShape({
    this.tickMarkRadius,
  });

  final double? tickMarkRadius;

  @override
  Size getPreferredSize({
    required SliderThemeData sliderTheme,
    required bool isEnabled,
  }) {
    assert(sliderTheme != null);
    assert(sliderTheme.trackHeight != null);
    assert(isEnabled != null);
    return Size.fromRadius(tickMarkRadius ?? sliderTheme.trackHeight! / 4);
  }

  @override
  void paint(
      PaintingContext context,
      Offset center, {
        required RenderBox parentBox,
        required SliderThemeData sliderTheme,
        required Animation<double> enableAnimation,
        required TextDirection textDirection,
        required Offset thumbCenter,
        required bool isEnabled,
      }) {
    Color? begin;
    Color? end;
    switch (textDirection) {
      case TextDirection.ltr:
        final bool isTickMarkRightOfThumb = center.dx > thumbCenter.dx;
        begin = isTickMarkRightOfThumb ? sliderTheme.disabledInactiveTickMarkColor : sliderTheme.disabledActiveTickMarkColor;
        end = isTickMarkRightOfThumb ? sliderTheme.inactiveTickMarkColor : sliderTheme.activeTickMarkColor;
        break;
      case TextDirection.rtl:
        final bool isTickMarkLeftOfThumb = center.dx < thumbCenter.dx;
        begin = isTickMarkLeftOfThumb ? sliderTheme.disabledInactiveTickMarkColor : sliderTheme.disabledActiveTickMarkColor;
        end = isTickMarkLeftOfThumb ? sliderTheme.inactiveTickMarkColor : sliderTheme.activeTickMarkColor;
        break;
    }
    final Paint paint = Paint()..color = ColorTween(begin: begin, end: end).evaluate(enableAnimation)!;

    final double tickMarkRadius = getPreferredSize(
      isEnabled: isEnabled,
      sliderTheme: sliderTheme,
    ).width / 2;
    if (tickMarkRadius > 0) {
      context.canvas.drawLine(Offset(center.dx - 5, center.dy - 5), Offset(center.dx + 5, center.dy + 5), paint);
    }
  }
}

一旦定义了LineSliderTickMarkShape,您可以像这样使用它来自定义您的滑块:

  @override
  Widget build(BuildContext context) {
    return SliderTheme(
      data: SliderTheme.of(context).copyWith(
        trackHeight: 20,
          tickMarkShape: const LineSliderTickMarkShape()
      ),
      child: Slider(
      ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接