Flutter_Slider_SliderTheme_滑杆/滑块_渐变色

  • 调用示例以及效果
		SliderTheme(
            data: SliderTheme.of(context).copyWith(
              trackHeight: 3,
              // 滑杆
              trackShape: const GradientRectSliderTrackShape(radius: 1.5),
              // 滑块
              thumbShape: const GradientSliderComponentShape(
                  rectWH: 14, overlayRectSpace: 4, overlayColor: Colours.black),
            ),
            child: Slider(
              value: 3,
              // 未滑动区域颜色
              inactiveColor: Color(0x55FFFFFF),
              min: 1,
              max: 10),
          )

UI效果

  • 滑杆渐变色
import 'package:flutter/material.dart';

class GradientRectSliderTrackShape extends SliderTrackShape
    with BaseSliderTrackShape {
  final double disabledThumbGapWidth;
  final double radius;
  final LinearGradient gradient;

  /// Creates a slider track that draws 2 rectangles.
  const GradientRectSliderTrackShape(
      {this.disabledThumbGapWidth = 2.0,
      this.radius = 0,
      this.gradient = const LinearGradient(
          colors: [Color(0xFFA2FFB7), Color(0xFF00FAED)])});

  
  Rect getPreferredRect({
    required RenderBox parentBox,
    Offset offset = Offset.zero,
    required SliderThemeData sliderTheme,
    bool isEnabled = false,
    bool isDiscrete = false,
  }) {
    final double overlayWidth =
        sliderTheme.overlayShape!.getPreferredSize(isEnabled, isDiscrete).width;
    final double trackHeight = sliderTheme.trackHeight ?? 2;
    assert(overlayWidth >= 0);
    assert(trackHeight >= 0);
    assert(parentBox.size.width >= overlayWidth);
    assert(parentBox.size.height >= trackHeight);

    final double trackLeft = offset.dx + overlayWidth / 2;
    final double trackTop =
        offset.dy + (parentBox.size.height - trackHeight) / 2;

    final double trackWidth = parentBox.size.width - overlayWidth;
    return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
  }

  
  void paint(
    PaintingContext context,
    Offset offset, {
    required RenderBox parentBox,
    required SliderThemeData sliderTheme,
    required Animation<double> enableAnimation,
    required Offset thumbCenter,
    Offset? secondaryOffset,
    bool isEnabled = false,
    bool isDiscrete = false,
    required TextDirection textDirection,
  }) {
    assert(sliderTheme.disabledActiveTrackColor != null);
    assert(sliderTheme.disabledInactiveTrackColor != null);
    assert(sliderTheme.activeTrackColor != null);
    assert(sliderTheme.inactiveTrackColor != null);
    assert(sliderTheme.thumbShape != null);

    if (sliderTheme.trackHeight! <= 0) {
      return;
    }

    final Rect trackRect = getPreferredRect(
      parentBox: parentBox,
      offset: offset,
      sliderTheme: sliderTheme,
      isEnabled: isEnabled,
      isDiscrete: isDiscrete,
    );

    final ColorTween activeTrackColorTween = ColorTween(
        begin: sliderTheme.disabledActiveTrackColor,
        end: sliderTheme.activeTrackColor);

    final ColorTween inactiveTrackColorTween = ColorTween(
        begin: sliderTheme.disabledInactiveTrackColor,
        end: sliderTheme.inactiveTrackColor);

    final Paint activePaint = Paint()
      ..shader = gradient.createShader(trackRect)
      ..color = activeTrackColorTween.evaluate(enableAnimation)!;

    final Paint inactivePaint = Paint()
      ..color = inactiveTrackColorTween.evaluate(enableAnimation)!;

    final Paint leftTrackPaint;
    final Paint rightTrackPaint;

    switch (textDirection) {
      case TextDirection.ltr:
        leftTrackPaint = activePaint;
        rightTrackPaint = inactivePaint;
        break;
      case TextDirection.rtl:
        leftTrackPaint = inactivePaint;
        rightTrackPaint = activePaint;
        break;
    }
    double horizontalAdjustment = 0.0;
    if (!isEnabled) {
      final double disabledThumbRadius =
          sliderTheme.thumbShape!.getPreferredSize(false, isDiscrete).width /
              2.0;
      final double gap = disabledThumbGapWidth * (1.0 - enableAnimation.value);
      horizontalAdjustment = disabledThumbRadius + gap;
    }

    //进度条两头圆角
    final RRect leftTrackSegment = RRect.fromLTRBR(
        trackRect.left,
        trackRect.top,
        thumbCenter.dx - horizontalAdjustment,
        trackRect.bottom,
        Radius.circular(radius));
    context.canvas.drawRRect(leftTrackSegment, leftTrackPaint);
    final RRect rightTrackSegment = RRect.fromLTRBR(
        thumbCenter.dx + horizontalAdjustment,
        trackRect.top,
        trackRect.right,
        trackRect.bottom,
        Radius.circular(radius));
    context.canvas.drawRRect(rightTrackSegment, rightTrackPaint);
  }
}

  • 滑块渐变色
import 'package:flutter/material.dart';

class GradientSliderComponentShape extends SliderComponentShape {
  final double rectWH;
  final double overlayRectSpace;
  final LinearGradient thumbGradient;
  final Color? overlayColor;
  const GradientSliderComponentShape(
      {required this.rectWH,
      required this.overlayRectSpace,
      this.thumbGradient =
          const LinearGradient(colors: [Color(0xFFA2FFB7), Color(0xFF00FAED)]),
      this.overlayColor});

  
  Size getPreferredSize(bool isEnabled, bool isDiscrete) {
    return const Size(0, 0);
  }

  
  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 canvas = context.canvas;
    // 点击滑块时阴影
    // canvas.drawShadow(
    //     Path()
    //       ..addRRect(RRect.fromRectAndRadius(
    //         Rect.fromCenter(center: center, width: 38, height: 34),
    //         const Radius.circular(19),
    //       )),
    //     Colors.red,
    //     5,
    //     false);
    double overlayWH = rectWH + overlayRectSpace;
    // 滑块描边
    canvas.drawRRect(
      RRect.fromRectAndRadius(
        Rect.fromCenter(center: center, width: overlayWH, height: overlayWH),
        Radius.circular(overlayWH / 2),
      ),
      Paint()
        ..color = (overlayColor != null)
            ? overlayColor!
            : const Color.fromARGB(255, 252, 241, 216),
    );
    // 滑块内
    canvas.drawRRect(
        RRect.fromRectAndRadius(
          Rect.fromCenter(center: center, width: rectWH, height: rectWH),
          Radius.circular(rectWH / 2),
        ),
        Paint()
          ..shader = thumbGradient.createShader(
              Rect.fromCenter(center: center, width: rectWH, height: rectWH)));
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值