Flutter - How to add a widget inside the track of a Slider widget

548 views Asked by At

I have a simple Slider widget and I want to add multiple containers inside the track at different points.

Needed Outcome Image enter image description here

Current Code

Slider(
  max: 500,
  value: _playerValue, 
  onChanged: (double value){
    setState(() {
      _playerValue = value;
    });
  },
),
1

There are 1 answers

0
Arun On BEST ANSWER

I do not think this is possible only by using the SliderThemeData; or at least, no way that I am aware of. However, you can achieve this behaviour using Stack, with the markers shown behind a translucent track of the slider. Demo snippet below.

One thing to note is to make sure the container that has the stack of markers has horizontal margin that is same as the slider's overlay radius; otherwise, the marker container becomes wider than the track.

IMPORTANT: I put this snippet together rapidly only to demonstrate the possibility of showing markers behind a slider's track. The dimensions of the track and the markers are hard-coded, which is very likely not what you want. I do not recommend using it as is, but only as a guide.

enter image description here

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Slider with Markers',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        brightness: Brightness.dark,
      ),
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  Home({Key? key}) : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  double sliderValue = 50;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text("Slider With Markers"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            SliderTheme(
              data: SliderTheme.of(context).copyWith(
                activeTrackColor: Colors.white60,
                inactiveTrackColor: Colors.white30,
                thumbColor: Colors.white,
                thumbShape: RoundSliderThumbShape(enabledThumbRadius: 10),
                overlayShape: RoundSliderOverlayShape(overlayRadius: 12),
                trackHeight: 12,
              ),
              child: Stack(
                alignment: Alignment.center,
                children: [
                  Container(
                    width: double.infinity,
                    margin: const EdgeInsets.symmetric(horizontal: 12),
                    child: Stack(
                      alignment: Alignment.centerLeft,
                      children: <Widget>[
                        marker(left: 15, width: 30),
                        marker(left: 150, width: 50),
                        marker(left: 300, width: 100),
                      ],
                    ),
                  ),
                  Slider(
                    value: sliderValue,
                    min: 0,
                    max: 100,
                    onChanged: ((value) {
                      setState(() {
                        sliderValue = value;
                      });
                    }),
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }

  Widget marker({required double left, required double width}) {
    return Container(
      height: 12,
      width: width,
      margin: EdgeInsets.only(left: left),
      decoration: BoxDecoration(
        color: Colors.amber,
        borderRadius: BorderRadius.circular(18),
      ),
    );
  }
}