42

Is it possible to customize a Slider Widget in Flutter?

Like this:

enter image description here

MendelG
  • 14,885
  • 4
  • 25
  • 52
Marcel Golob
  • 451
  • 1
  • 5
  • 9
  • If you ask about Slider thumb Image, please check this answer https://stackoverflow.com/questions/58116843/flutter-how-to-add-thumb-image-to-slider – Abjox Dec 29 '19 at 11:01

3 Answers3

55

Wrap your slider with a SliderTheme

SliderTheme(
    data: SliderThemeData(
            thumbColor: Colors.green,
            thumbShape: RoundSliderThumbShape(enabledThumbRadius: 20)),
    child: Slider(
          value: _value,
          onChanged: (val) {
            _value = val;
            setState(() {});
          },
        ),
      ),

Sergio Bernal
  • 2,126
  • 9
  • 20
  • 2
    But how to add custom Icon on thumbShape? – – Marcel Golob Jul 18 '19 at 09:51
  • 7
    You have to create a custom thumb by extending from `SliderComponentShape` and override the `paint` method. Then, inside the `paint` method use `context.canvas` to draw your custom shape. Check `canvas.drawImage` to use an image if you want to use an image. – Sergio Bernal Jul 24 '19 at 21:51
  • 1
    @MarcelGolob this blog post discuss how to do it: https://medium.com/flutter-community/flutter-sliders-demystified-4b3ea65879c – Ulysses Alves Oct 09 '21 at 20:01
13

I think you have to use the SliderTickMarkShape class

Base class for Slider tick mark shapes.

Create a subclass of this if you would like a custom slider tick mark shape.

The easy way is to get the actual SliderTheme used in your context and modify only the properties you need. For example, to modify one slide:

SliderTheme(
    data: SliderTheme.of(context).copyWith(
    activeTrackColor: Colors.white,
    thumbShape: RoundSliderThumbShape(enabledThumbRadius: 15.0),
    overlayShape: RoundSliderOverlayShape(overlayRadius: 30.0),
    ),
    child: Slider(
             value: height.toDouble(),
             min: 120.0,
             max: 220.0,
             activeColor: Colors.white,
             inactiveColor: Color(0xFF8D8E98),
             onChanged: (double newValue) {
                 setState(() {
                        height = newValue.round();
                      });
                    },
                  ),
                ),

Another option is modify the theme you're using in your app; in this way you modify all the sliders in the app:

MaterialApp(
      theme: ThemeData.dark().copyWith(
          sliderTheme: SliderTheme.of(context).copyWith( //slider modifications
            thumbColor: Color(0xFFEB1555),
            inactiveTrackColor: Color(0xFF8D8E98),
            activeTrackColor: Colors.white,
            overlayColor: Color(0x99EB1555),
            thumbShape: RoundSliderThumbShape(enabledThumbRadius: 15.0),
            overlayShape: RoundSliderOverlayShape(overlayRadius: 30.0),
          ),
          primaryColor: Color(0xFF0A0E21), // theme color
          scaffoldBackgroundColor: Color(0xFF0A0E21)), // theme background color
      home: InputPage(),
);
abanet
  • 1,327
  • 17
  • 22
5

I remember , I had the same challenge.

I create my own wave slider:

import 'dart:math';

import 'package:flutter/material.dart';

List<int> bars = [];
const barWidth = 5.0;
double screenWidth;
int numberOfBars;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home(),
    );
  }
}

void randomNumberGenerator() {
  Random r = Random();
  for (var i = 0; i < numberOfBars; i++) {
    bars.add(r.nextInt(40) + 10);
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    if (bars.isEmpty) {
      screenWidth = MediaQuery.of(context).size.width;
      numberOfBars = screenWidth ~/ barWidth;
      randomNumberGenerator();
    }
    return Container(child: WaveSlider());
  }
}

class WaveSlider extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => WaveSliderState();
}

class WaveSliderState extends State<WaveSlider> {
  double bar2Position = 180.0;

  _onTapDown(TapDownDetails details) {
    var x = details.globalPosition.dx;
    print("tap down " + x.toString());
    setState(() {
      bar2Position = x;
    });
  }

  @override
  Widget build(BuildContext context) {
    int barItem = 0;
    return Scaffold(
      body: Center(
        child: Stack(
          alignment: Alignment.centerLeft,
          children: <Widget>[
            GestureDetector(
              onTapDown: (TapDownDetails details) => _onTapDown(details),
              onHorizontalDragUpdate: (DragUpdateDetails details) {
                setState(() {
                  bar2Position = details.globalPosition.dx;
                });
              },
              child: Container(
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: bars.map((int height) {
                    Color color = barItem + 1 < bar2Position / barWidth
                        ? Colors.deepPurple
                        : Colors.blueGrey;
                    barItem++;
                    return Container(
                      color: color,
                      height: height.toDouble(),
                      width: 5.0,
                    );
                  }).toList(),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

mohammad
  • 2,568
  • 3
  • 20
  • 41