skip to Main Content

This is the picture i got from Syncfusion’s docs.

Syncfusion Slider

enter image description here

Here’s what I want to achieve,
A slider track which has active color, inactive color, and a disabled color.
the disabled color will be applied between the user’s value to max value.

lets say, I input value of 80, thus the color red will be applied between 80 – 100.

I’ve tried restricting the onChanged property to not go over the user’s given value. i.e 80.
I just need the color to be different between users value – max value.

2

Answers


  1. You may try like this

     double _values = 80;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SfSlider(
            min: 0.0,
            max: 100.0,
        stepSize: 1,
        value: _values,
        inactiveColor: Colors.red.shade200,
        activeColor: Colors.green,
        interval: 20,
        showTicks: true,
        showLabels: true,
        enableTooltip: true,
        minorTicksPerInterval: 1,
        onChanged: (value) {
          setState(() {
            _values = value;
          });
        },
      ),
    );
    }
    
    Login or Signup to reply.
  2. We have achieved your requirements using the trackShape and thumShape properties in the Slider. We extended the SfTrackShape and SfThumbShape classes and customized the track and thumb colors based on the slider values in the paint method. We have then assigned these classes to the trackShape and thumShape properties. We have shared the complete code snippet below for your reference.

    Code snippet:

    import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_sliders/sliders.dart';
    import 'package:syncfusion_flutter_core/theme.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const ShapeCustomizedSliderPage(Key('slider')),
        );
      }
    }
    
    ///Renders slider with customized shapes
    class ShapeCustomizedSliderPage extends StatefulWidget {
      ///Renders slider with customized shapes
      const ShapeCustomizedSliderPage(Key key) : super(key: key);
    
      @override
      ShapeCustomizedSliderPageState createState() =>
          ShapeCustomizedSliderPageState();
    }
    
    class ShapeCustomizedSliderPageState extends State<ShapeCustomizedSliderPage> {
      ShapeCustomizedSliderPageState();
      final double _min = 0.0;
      final double _max = 100.0;
      double _value = 60.0;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: LayoutBuilder(
              builder: (BuildContext context, BoxConstraints constraints) {
            final double padding = MediaQuery.of(context).size.width / 20.0;
            return Container(
              padding: EdgeInsets.fromLTRB(padding, 0, padding, 0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  SfSliderTheme(
                    data: SfSliderThemeData(
                      brightness: Brightness.light,
                    ),
                    child: SfSlider(
                      min: _min,
                      max: _max,
                      value: _value,
                      interval: 20.0,
                      showLabels: true,
                      showTicks: true,
                      trackShape: _SfTrackShape(_min, _max),
                      thumbShape: _SfThumbShape(_min, _max),
                      onChanged: (dynamic value) {
                        setState(() {
                          _value = value as double;
                        });
                      },
                    ),
                  ),
                ],
              ),
            );
          }),
        );
      }
    }
    
    class _SfTrackShape extends SfTrackShape {
      _SfTrackShape(dynamic min, dynamic max) {
        this.min = (min.runtimeType == DateTime
            ? min.millisecondsSinceEpoch.toDouble()
            : min) as double;
        this.max = (max.runtimeType == DateTime
            ? max.millisecondsSinceEpoch.toDouble()
            : max) as double;
      }
    
      late double min;
      late double max;
      double? trackIntermediatePos;
    
      @override
      void paint(PaintingContext context, Offset offset, Offset? thumbCenter,
          Offset? startThumbCenter, Offset? endThumbCenter,
          {required RenderBox parentBox,
          required SfSliderThemeData themeData,
          SfRangeValues? currentValues,
          dynamic currentValue,
          required Animation<double> enableAnimation,
          required Paint? inactivePaint,
          required Paint? activePaint,
          required TextDirection textDirection}) {
        final Rect trackRect = getPreferredRect(parentBox, themeData, offset);
        final double actualValue = (currentValue.runtimeType == DateTime
            ? currentValue.millisecondsSinceEpoch.toDouble()
            : currentValue) as double;
        final double actualValueInPercent =
            ((actualValue - min) * 100) / (max - min);
        trackIntermediatePos = _getTrackIntermediatePosition(trackRect);
    
        // low volume track.
        final Paint trackPaint = Paint();
        trackPaint.color = actualValueInPercent <= 80.0 ? Colors.green : Colors.red;
        final Rect lowVolumeRect = Rect.fromLTRB(
            trackRect.left, trackRect.top, thumbCenter!.dx, trackRect.bottom);
        context.canvas.drawRect(lowVolumeRect, trackPaint);
    
        if (actualValueInPercent <= 80.0) {
          trackPaint.color = Colors.green.withOpacity(0.40);
          final Rect lowVolumeRectWithLessOpacity = Rect.fromLTRB(thumbCenter.dx,
              trackRect.top, trackIntermediatePos!, trackRect.bottom);
          context.canvas.drawRect(lowVolumeRectWithLessOpacity, trackPaint);
        }
    
        trackPaint.color = Colors.red.withOpacity(0.40);
        final double highTrackLeft =
            actualValueInPercent >= 80.0 ? thumbCenter.dx : trackIntermediatePos!;
        final Rect highVolumeRectWithLessOpacity = Rect.fromLTRB(highTrackLeft,
            trackRect.top, trackRect.width + trackRect.left, trackRect.bottom);
        context.canvas.drawRect(highVolumeRectWithLessOpacity, trackPaint);
      }
    
      double _getTrackIntermediatePosition(Rect trackRect) {
        final double actualValue = ((80 * (max - min)) + min) / 100;
        return (((actualValue - min) / (max - min)) * trackRect.width) +
            trackRect.left;
      }
    }
    
    class _SfThumbShape extends SfThumbShape {
      _SfThumbShape(dynamic min, dynamic max) {
        this.min = (min.runtimeType == DateTime
            ? min.millisecondsSinceEpoch.toDouble()
            : min) as double;
        this.max = (max.runtimeType == DateTime
            ? max.millisecondsSinceEpoch.toDouble()
            : max) as double;
      }
    
      late double min;
      late double max;
    
      @override
      void paint(PaintingContext context, Offset center,
          {required RenderBox parentBox,
          required RenderBox? child,
          required SfSliderThemeData themeData,
          SfRangeValues? currentValues,
          dynamic currentValue,
          required Paint? paint,
          required Animation<double> enableAnimation,
          required TextDirection textDirection,
          required SfThumb? thumb}) {
        final double actualValue = (currentValue.runtimeType == DateTime
            ? currentValue.millisecondsSinceEpoch.toDouble()
            : currentValue) as double;
    
        final double actualValueInPercent =
            ((actualValue - min) * 100) / (max - min);
    
        paint = Paint();
        paint.color = actualValueInPercent <= 80 ? Colors.green : Colors.red;
    
        super.paint(context, center,
            parentBox: parentBox,
            themeData: themeData,
            currentValue: currentValue,
            paint: paint,
            enableAnimation: enableAnimation,
            textDirection: textDirection,
            thumb: thumb,
            child: child);
      }
    }
    

    Screenshot:
    enter image description here

    Live Sample, https://flutter.syncfusion.com/#/slider/customization/shape-customization

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search